Печать Even and Odd с использованием двух streamов в Java

Я попробовал код ниже. Я взял этот кусок кода из какой-то другой статьи, которая правильна в соответствии с автором. Но когда я пытаюсь работать, это не дает мне точного результата.

Это в основном для непрерывной печати четных и нечетных значений.

public class PrintEvenOddTester { public static void main(String ... args){ Printer print = new Printer(false); Thread t1 = new Thread(new TaskEvenOdd(print)); Thread t2 = new Thread(new TaskEvenOdd(print)); t1.start(); t2.start(); } } class TaskEvenOdd implements Runnable { int number=1; Printer print; TaskEvenOdd(Printer print){ this.print = print; } @Override public void run() { System.out.println("Run method"); while(number<10){ if(number%2 == 0){ System.out.println("Number is :"+ number); print.printEven(number); number+=2; } else { System.out.println("Number is :"+ number); print.printOdd(number); number+=2; } } } } class Printer { boolean isOdd; Printer(boolean isOdd){ this.isOdd = isOdd; } synchronized void printEven(int number) { while(isOdd){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Even:"+number); isOdd = true; notifyAll(); } synchronized void printOdd(int number) { while(!isOdd){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Odd:"+number); isOdd = false; notifyAll(); } } 

Может ли кто-нибудь помочь мне в исправлении этого?

EDIT Ожидаемый результат: Нечетный: 1 Четный: 2 Нечетный: 3 Четный: 4 Нечетный: 5 Четный: 6 Нечетный: 7 Четный: 8 Нечетный: 9

Нашел решение. Кто-то, кто ищет решение этой проблемы, может ссылаться 🙂

 public class PrintEvenOddTester { public static void main(String... args) { Printer print = new Printer(); Thread t1 = new Thread(new TaskEvenOdd(print, 10, false)); Thread t2 = new Thread(new TaskEvenOdd(print, 10, true)); t1.start(); t2.start(); } } class TaskEvenOdd implements Runnable { private int max; private Printer print; private boolean isEvenNumber; TaskEvenOdd(Printer print, int max, boolean isEvenNumber) { this.print = print; this.max = max; this.isEvenNumber = isEvenNumber; } @Override public void run() { //System.out.println("Run method"); int number = isEvenNumber == true ? 2 : 1; while (number <= max) { if (isEvenNumber) { //System.out.println("Even :"+ Thread.currentThread().getName()); print.printEven(number); //number+=2; } else { //System.out.println("Odd :"+ Thread.currentThread().getName()); print.printOdd(number); // number+=2; } number += 2; } } } class Printer { boolean isOdd = false; synchronized void printEven(int number) { while (isOdd == false) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Even:" + number); isOdd = false; notifyAll(); } synchronized void printOdd(int number) { while (isOdd == true) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Odd:" + number); isOdd = true; notifyAll(); } } 

Это дает результат:

 Odd:1 Even:2 Odd:3 Even:4 Odd:5 Even:6 Odd:7 Even:8 Odd:9 Even:10 

Вот код, который я сделал, чтобы он работал через один class

 package com.learn.thread; public class PrintNumbers extends Thread { volatile static int i = 1; Object lock; PrintNumbers(Object lock) { this.lock = lock; } public static void main(String ar[]) { Object obj = new Object(); // This constructor is required for the identification of wait/notify // communication PrintNumbers odd = new PrintNumbers(obj); PrintNumbers even = new PrintNumbers(obj); odd.setName("Odd"); even.setName("Even"); odd.start(); even.start(); } @Override public void run() { while (i <= 10) { if (i % 2 == 0 && Thread.currentThread().getName().equals("Even")) { synchronized (lock) { System.out.println(Thread.currentThread().getName() + " - " + i); i++; try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } if (i % 2 == 1 && Thread.currentThread().getName().equals("Odd")) { synchronized (lock) { System.out.println(Thread.currentThread().getName() + " - " + i); i++; lock.notify(); } } } } } 

Вывод:

 Odd - 1 Even - 2 Odd - 3 Even - 4 Odd - 5 Even - 6 Odd - 7 Even - 8 Odd - 9 Even - 10 Odd - 11 
  private Object lock = new Object(); private volatile boolean isOdd = false; public void generateEvenNumbers(int number) throws InterruptedException { synchronized (lock) { while (isOdd == false) { lock.wait(); } System.out.println(number); isOdd = false; lock.notifyAll(); } } public void generateOddNumbers(int number) throws InterruptedException { synchronized (lock) { while (isOdd == true) { lock.wait(); } System.out.println(number); isOdd = true; lock.notifyAll(); } } 

Используйте следующую простую функцию JawA 8 Runnable Class

 public class MultiThreadExample { static AtomicBoolean isEven = new AtomicBoolean(false); static AtomicInteger atomicNumber = new AtomicInteger(1); static Object object = new Object(); public static void main(String[] args) { Runnable print = () -> { while (atomicNumber.get() < 10) { synchronized (object) { if ((atomicNumber.get() % 2 == 0) && "Even".equals(Thread.currentThread().getName())) { System.out.println("Even" + ":" + atomicNumber.getAndIncrement()); } else if ((atomicNumber.get() % 2 != 0) && "Odd".equals(Thread.currentThread().getName())) { System.out.println("Odd" + ":" + atomicNumber.getAndIncrement()); } } } }; Thread t1 = new Thread(print); t1.setName("Even"); t1.start(); Thread t2 = new Thread(print); t2.setName("Odd"); t2.start(); } } 

То же самое можно сделать с помощью интерфейса Lock:

 import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class NumberPrinter implements Runnable { private Lock lock; private Condition condition; private String type; private static boolean oddTurn = true; public NumberPrinter(String type, Lock lock, Condition condition) { this.type = type; this.lock = lock; this.condition = condition; } public void run() { int i = type.equals("odd") ? 1 : 2; while (i <= 10) { if (type.equals("odd")) printOdd(i); if (type.equals("even")) printEven(i); i = i + 2; } } private void printOdd(int i) { // synchronized (lock) { lock.lock(); while (!oddTurn) { try { // lock.wait(); condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(type + " " + i); oddTurn = false; // lock.notifyAll(); condition.signalAll(); lock.unlock(); } // } private void printEven(int i) { // synchronized (lock) { lock.lock(); while (oddTurn) { try { // lock.wait(); condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(type + " " + i); oddTurn = true; // lock.notifyAll(); condition.signalAll(); lock.unlock(); } // } public static void main(String[] args) { Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); Thread odd = new Thread(new NumberPrinter("odd", lock, condition)); Thread even = new Thread(new NumberPrinter("even", lock, condition)); odd.start(); even.start(); } } 
 Simpler Version in Java 8: public class EvenOddPrinter { static boolean flag = true; public static void main(String[] args) { Runnable odd = () -> { for (int i = 1; i <= 10;) { if(EvenOddPrinter.flag) { System.out.println(i); i+=2; EvenOddPrinter.flag = !EvenOddPrinter.flag; } } }; Runnable even = () -> { for (int i = 2; i <= 10;) { if(!EvenOddPrinter.flag) { System.out.println(i); i+=2; EvenOddPrinter.flag = !EvenOddPrinter.flag; } } }; Thread t1 = new Thread(odd, "Odd"); Thread t2 = new Thread(even, "Even"); t1.start(); t2.start(); } } 

Этот код также будет работать нормально.

 class Thread1 implements Runnable { private static boolean evenFlag = true; public synchronized void run() { if (evenFlag == true) { printEven(); } else { printOdd(); } } public void printEven() { for (int i = 0; i <= 10; i += 2) { System.out.println(i+""+Thread.currentThread()); } evenFlag = false; } public void printOdd() { for (int i = 1; i <= 11; i += 2) { System.out.println(i+""+Thread.currentThread()); } evenFlag = true; } } public class OddEvenDemo { public static void main(String[] args) { Thread1 t1 = new Thread1(); Thread td1 = new Thread(t1); Thread td2 = new Thread(t1); td1.start(); td2.start(); } } 
 import java.util.concurrent.atomic.AtomicInteger; public class PrintEvenOddTester { public static void main(String ... args){ Printer print = new Printer(false); Thread t1 = new Thread(new TaskEvenOdd(print, "Thread1", new AtomicInteger(1))); Thread t2 = new Thread(new TaskEvenOdd(print,"Thread2" , new AtomicInteger(2))); t1.start(); t2.start(); } } class TaskEvenOdd implements Runnable { Printer print; String name; AtomicInteger number; TaskEvenOdd(Printer print, String name, AtomicInteger number){ this.print = print; this.name = name; this.number = number; } @Override public void run() { System.out.println("Run method"); while(number.get()<10){ if(number.get()%2 == 0){ print.printEven(number.get(),name); } else { print.printOdd(number.get(),name); } number.addAndGet(2); } } } class Printer { boolean isEven; public Printer() { } public Printer(boolean isEven) { this.isEven = isEven; } synchronized void printEven(int number, String name) { while (!isEven) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(name+": Even:" + number); isEven = false; notifyAll(); } synchronized void printOdd(int number, String name) { while (isEven) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(name+": Odd:" + number); isEven = true; notifyAll(); } } в import java.util.concurrent.atomic.AtomicInteger; public class PrintEvenOddTester { public static void main(String ... args){ Printer print = new Printer(false); Thread t1 = new Thread(new TaskEvenOdd(print, "Thread1", new AtomicInteger(1))); Thread t2 = new Thread(new TaskEvenOdd(print,"Thread2" , new AtomicInteger(2))); t1.start(); t2.start(); } } class TaskEvenOdd implements Runnable { Printer print; String name; AtomicInteger number; TaskEvenOdd(Printer print, String name, AtomicInteger number){ this.print = print; this.name = name; this.number = number; } @Override public void run() { System.out.println("Run method"); while(number.get()<10){ if(number.get()%2 == 0){ print.printEven(number.get(),name); } else { print.printOdd(number.get(),name); } number.addAndGet(2); } } } class Printer { boolean isEven; public Printer() { } public Printer(boolean isEven) { this.isEven = isEven; } synchronized void printEven(int number, String name) { while (!isEven) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(name+": Even:" + number); isEven = false; notifyAll(); } synchronized void printOdd(int number, String name) { while (isEven) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(name+": Odd:" + number); isEven = true; notifyAll(); } } 

Другой вопрос был закрыт как дубликат этого. Я думаю, что мы можем безопасно избавиться от «четной или нечетной» проблемы и использовать конструкцию wait/notify следующим образом:

 public class WaitNotifyDemoEvenOddThreads { /** * A transfer object, only use with proper client side locking! */ static final class LastNumber { int num; final int limit; LastNumber(int num, int limit) { this.num = num; this.limit = limit; } } static final class NumberPrinter implements Runnable { private final LastNumber last; private final int init; NumberPrinter(LastNumber last, int init) { this.last = last; this.init = init; } @Override public void run() { int i = init; synchronized (last) { while (i <= last.limit) { while (last.num != i) { try { last.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + " prints: " + i); last.num = i + 1; i += 2; last.notify(); } } } } public static void main(String[] args) { LastNumber last = new LastNumber(0, 10); // or 0, 1000 NumberPrinter odd = new NumberPrinter(last, 1); NumberPrinter even = new NumberPrinter(last, 0); new Thread(odd, "o").start(); new Thread(even, "e").start(); } } 
 package pkgscjp; public class OddPrint implements Runnable { public static boolean flag = true; public void run() { for (int i = 1; i <= 99;) { if (flag) { System.out.println(i); flag = false; i = i + 2; } } } } package pkgscjp; public class EvenPrint implements Runnable { public void run() { for (int i = 2; i <= 100;) { if (!OddPrint.flag) { System.out.println(i); OddPrint.flag = true; i = i + 2; } } } } package pkgscjp; public class NaturalNumberThreadMain { public static void main(String args[]) { EvenPrint ep = new EvenPrint(); OddPrint op = new OddPrint(); Thread te = new Thread(ep); Thread to = new Thread(op); to.start(); te.start(); } } 

Я сделал это таким образом, при печати с использованием двух streamов мы не можем предсказать последовательность, какая нить
сначала будет выполнено, чтобы преодолеть эту ситуацию, мы должны синхронизировать общий ресурс, в
в моем случае используется функция печати, к которой обращаются два streamа.

 class Printoddeven{ public synchronized void print(String msg) { try { if(msg.equals("Even")) { for(int i=0;i<=10;i+=2) { System.out.println(msg+" "+i); Thread.sleep(2000); notify(); wait(); } } else { for(int i=1;i<=10;i+=2) { System.out.println(msg+" "+i); Thread.sleep(2000); notify(); wait(); } } } catch (Exception e) { e.printStackTrace(); } } } class PrintOdd extends Thread{ Printoddeven oddeven; public PrintOdd(Printoddeven oddeven){ this.oddeven=oddeven; } public void run(){ oddeven.print("ODD"); } } class PrintEven extends Thread{ Printoddeven oddeven; public PrintEven(Printoddeven oddeven){ this.oddeven=oddeven; } public void run(){ oddeven.print("Even"); } } public class mainclass { public static void main(String[] args) { Printoddeven obj = new Printoddeven();//only one object PrintEven t1=new PrintEven(obj); PrintOdd t2=new PrintOdd(obj); t1.start(); t2.start(); } } 

Это мое решение проблемы. У меня есть два classа, реализующие Runnable , один печатает нечетную последовательность и другие отпечатки. У меня есть экземпляр Object , который я использую для блокировки. Я инициализирую два classа одним и тем же объектом. В методе запуска двух classов есть synchronized block , где внутри цикла каждый метод печатает одно из чисел, уведомляет о другом streamе, ожидая блокировки на одном и том же объекте, а затем сам снова ждет тот же самый замок.

Классы :

 public class PrintEven implements Runnable{ private Object lock; public PrintEven(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { for (int i = 2; i <= 10; i+=2) { System.out.println("EVEN:="+i); lock.notify(); try { //if(i!=10) lock.wait(); lock.wait(500); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public class PrintOdd implements Runnable { private Object lock; public PrintOdd(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { for (int i = 1; i <= 10; i+=2) { System.out.println("ODD:="+i); lock.notify(); try { //if(i!=9) lock.wait(); lock.wait(500); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public class PrintEvenOdd { public static void main(String[] args){ Object lock = new Object(); Thread thread1 = new Thread(new PrintOdd(lock)); Thread thread2 = new Thread(new PrintEven(lock)); thread1.start(); thread2.start(); } } 

Верхний предел в моем примере равен 10. Как только нечетный stream печатает 9 или четные оттиски streamов 10, нам не нужен ни один из streamов, чтобы ждать больше. Таким образом, мы можем справиться с этим, используя один if-block . Или мы можем использовать метод перегруженного wait(long timeout) для ожидания ожидания. Однако здесь есть один недостаток. С помощью этого кода мы не можем гарантировать, какой stream начнет выполнение в первую очередь.

Вот рабочий код, чтобы печатать нечетные, даже не используя механизм ожидания и уведомления. Я ограничиваю предел чисел для печати от 1 до 50.

 public class NotifyTest { Object ob=new Object(); public static void main(String[] args) { // TODO Auto-generated method stub NotifyTest nt=new NotifyTest(); even e=new even(nt.ob); odd o=new odd(nt.ob); Thread t1=new Thread(e); Thread t2=new Thread(o); t1.start(); t2.start(); } } class even implements Runnable { Object lock; int i=2; public even(Object ob) { this.lock=ob; } @Override public void run() { // TODO Auto-generated method stub while(i<=50) { synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Even Thread Name-->>" + Thread.currentThread().getName() + "Value-->>" + i); i=i+2; } } } class odd implements Runnable { Object lock; int i=1; public odd(Object ob) { this.lock=ob; } @Override public void run() { // TODO Auto-generated method stub while(i<=49) { synchronized (lock) { System.out.println("Odd Thread Name-->>" + Thread.currentThread().getName() + "Value-->>" + i); i=i+2; lock.notify(); } try { Thread.sleep(1000); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } в public class NotifyTest { Object ob=new Object(); public static void main(String[] args) { // TODO Auto-generated method stub NotifyTest nt=new NotifyTest(); even e=new even(nt.ob); odd o=new odd(nt.ob); Thread t1=new Thread(e); Thread t2=new Thread(o); t1.start(); t2.start(); } } class even implements Runnable { Object lock; int i=2; public even(Object ob) { this.lock=ob; } @Override public void run() { // TODO Auto-generated method stub while(i<=50) { synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Even Thread Name-->>" + Thread.currentThread().getName() + "Value-->>" + i); i=i+2; } } } class odd implements Runnable { Object lock; int i=1; public odd(Object ob) { this.lock=ob; } @Override public void run() { // TODO Auto-generated method stub while(i<=49) { synchronized (lock) { System.out.println("Odd Thread Name-->>" + Thread.currentThread().getName() + "Value-->>" + i); i=i+2; lock.notify(); } try { Thread.sleep(1000); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } в public class NotifyTest { Object ob=new Object(); public static void main(String[] args) { // TODO Auto-generated method stub NotifyTest nt=new NotifyTest(); even e=new even(nt.ob); odd o=new odd(nt.ob); Thread t1=new Thread(e); Thread t2=new Thread(o); t1.start(); t2.start(); } } class even implements Runnable { Object lock; int i=2; public even(Object ob) { this.lock=ob; } @Override public void run() { // TODO Auto-generated method stub while(i<=50) { synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Even Thread Name-->>" + Thread.currentThread().getName() + "Value-->>" + i); i=i+2; } } } class odd implements Runnable { Object lock; int i=1; public odd(Object ob) { this.lock=ob; } @Override public void run() { // TODO Auto-generated method stub while(i<=49) { synchronized (lock) { System.out.println("Odd Thread Name-->>" + Thread.currentThread().getName() + "Value-->>" + i); i=i+2; lock.notify(); } try { Thread.sleep(1000); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } 

Ниже приводится моя реализация с использованием 2 Семафоров.

  1. Нечетный семафор с разрешением 1.
  2. Даже Семафор с разрешением 0.
  3. Передайте два Семафора в оба streamа как следующую подпись (мой, другой): –
  4. В Нечетный stream проходит в порядке (нечетное, четное)
  5. Для равномерного прохождения streamа в этом порядке (четный, нечетный)
  6. run () метод my.acquireUninterruptibly () -> Print -> other.release ()
  7. В streamе Even, поскольку даже Sema равен 0, он будет блокироваться.
  8. В нечетном streamе в качестве нечетного Sema доступно (от init до 1), это будет печатать 1, а затем освободить даже Sema, позволяющую запустить Even thread.
  9. Даже stream запускает отпечатки 2 и освобождает нечетную Sema, позволяющую запускать stream Odd.

     import java.util.concurrent.Semaphore; public class EvenOdd { private final static String ODD = "ODD"; private final static String EVEN = "EVEN"; private final static int MAX_ITERATIONS = 10; public static class EvenOddThread implements Runnable { private String mType; private int mNum; private Semaphore mMySema; private Semaphore mOtherSema; public EvenOddThread(String str, Semaphore mine, Semaphore other) { mType = str; mMySema = mine;//new Semaphore(1); // start out as unlocked mOtherSema = other;//new Semaphore(0); if(str.equals(ODD)) { mNum = 1; } else { mNum = 2; } } @Override public void run() { for (int i = 0; i < MAX_ITERATIONS; i++) { mMySema.acquireUninterruptibly(); if (mType.equals(ODD)) { System.out.println("Odd Thread - " + mNum); } else { System.out.println("Even Thread - " + mNum); } mNum += 2; mOtherSema.release(); } } } public static void main(String[] args) throws InterruptedException { Semaphore odd = new Semaphore(1); Semaphore even = new Semaphore(0); System.out.println("Start!!!"); System.out.println(); Thread tOdd = new Thread(new EvenOddThread(ODD, odd, even)); Thread tEven = new Thread(new EvenOddThread(EVEN, even, odd)); tOdd.start(); tEven.start(); tOdd.join(); tEven.join(); System.out.println(); System.out.println("Done!!!"); } } 

Ниже приводится результат: -

 Start!!! Odd Thread - 1 Even Thread - 2 Odd Thread - 3 Even Thread - 4 Odd Thread - 5 Even Thread - 6 Odd Thread - 7 Even Thread - 8 Odd Thread - 9 Even Thread - 10 Odd Thread - 11 Even Thread - 12 Odd Thread - 13 Even Thread - 14 Odd Thread - 15 Even Thread - 16 Odd Thread - 17 Even Thread - 18 Odd Thread - 19 Even Thread - 20 Done!!! 

Я думаю, что предоставляемые решения излишне добавляют материал и не используют семафоры в полном объеме. Вот мое решение.

 package com.test.threads; import java.util.concurrent.Semaphore; public class EvenOddThreadTest { public static int MAX = 100; public static Integer number = new Integer(0); //Unlocked state public Semaphore semaphore = new Semaphore(1); class PrinterThread extends Thread { int start = 0; String name; PrinterThread(String name ,int start) { this.start = start; this.name = name; } @Override public void run() { try{ while(start < MAX){ // try to acquire the number of semaphore equal to your value // and if you do not get it then wait for it. semaphore.acquire(start); System.out.println(name + " : " + start); // prepare for the next iteration. start+=2; // release one less than what you need to print in the next iteration. // This will release the other thread which is waiting to print the next number. semaphore.release(start-1); } } catch(InterruptedException e){ } } } public static void main(String args[]) { EvenOddThreadTest test = new EvenOddThreadTest(); PrinterThread a = test.new PrinterThread("Even",1); PrinterThread b = test.new PrinterThread("Odd", 2); try { a.start(); b.start(); } catch (Exception e) { } } } 
 package com.example; public class MyClass { static int mycount=0; static Thread t; static Thread t2; public static void main(String[] arg) { t2=new Thread(new Runnable() { @Override public void run() { System.out.print(mycount++ + " even \n"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } if(mycount>25) System.exit(0); run(); } }); t=new Thread(new Runnable() { @Override public void run() { System.out.print(mycount++ + " odd \n"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } if(mycount>26) System.exit(0); run(); } }); t.start(); t2.start(); } } 

Рабочее решение с использованием одного classа

 package com.fursa.threads; public class PrintNumbers extends Thread { Object lock; PrintNumbers(Object lock) { this.lock = lock; } public static void main(String ar[]) { Object obj = new Object(); // This constructor is required for the identification of wait/notify // communication PrintNumbers odd = new PrintNumbers(obj); PrintNumbers even = new PrintNumbers(obj); odd.setName("Odd"); even.setName("Even"); even.start(); odd.start(); } @Override public void run() { for(int i=0;i<=100;i++) { synchronized (lock) { if (Thread.currentThread().getName().equals("Even")) { if(i % 2 == 0 ){ System.out.println(Thread.currentThread().getName() + " - "+ i); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else if (i % 2 != 0 ) { lock.notify(); } } if (Thread.currentThread().getName().equals("Odd")) { if(i % 2 == 1 ){ System.out.println(Thread.currentThread().getName() + " - "+ i); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else if (i % 2 != 1 ) { lock.notify(); } } } } } } 

Вы можете использовать следующий код, чтобы получить результат с созданием двух анонимных classов streamов.

 package practice; class Display { boolean isEven = false; synchronized public void printEven(int number) throws InterruptedException { while (isEven) wait(); System.out.println("Even : " + number); isEven = true; notify(); } synchronized public void printOdd(int number) throws InterruptedException { while (!isEven) wait(); System.out.println("Odd : " + number); isEven = false; notify(); } } public class OddEven { public static void main(String[] args) { // TODO Auto-generated method stub final Display disp = new Display(); new Thread() { public void run() { int num = 0; for (int i = num; i <= 10; i += 2) { try { disp.printEven(i); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }.start(); new Thread() { public void run() { int num = 1; for (int i = num; i <= 10; i += 2) { try { disp.printOdd(i); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }.start(); } } 

Это может быть достигнуто с помощью Lock и Condition:

 import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class EvenOddThreads { public static void main(String[] args) throws InterruptedException { Printer p = new Printer(); Thread oddThread = new Thread(new PrintThread(p,false),"Odd :"); Thread evenThread = new Thread(new PrintThread(p,true),"Even :"); oddThread.start(); evenThread.start(); } } class PrintThread implements Runnable{ Printer p; boolean isEven = false; PrintThread(Printer p, boolean isEven){ this.p = p; this.isEven = isEven; } @Override public void run() { int i = (isEven==true) ? 2 : 1; while(i < 10 ){ if(isEven){ p.printEven(i); }else{ p.printOdd(i); } i=i+2; } } } class Printer{ boolean isEven = true; Lock lock = new ReentrantLock(); Condition condEven = lock.newCondition(); Condition condOdd = lock.newCondition(); public void printEven(int no){ lock.lock(); while(isEven==true){ try { condEven.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() +no); isEven = true; condOdd.signalAll(); lock.unlock(); } public void printOdd(int no){ lock.lock(); while(isEven==false){ try { condOdd.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() +no); isEven = false; condEven.signalAll(); lock.unlock(); } } в import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class EvenOddThreads { public static void main(String[] args) throws InterruptedException { Printer p = new Printer(); Thread oddThread = new Thread(new PrintThread(p,false),"Odd :"); Thread evenThread = new Thread(new PrintThread(p,true),"Even :"); oddThread.start(); evenThread.start(); } } class PrintThread implements Runnable{ Printer p; boolean isEven = false; PrintThread(Printer p, boolean isEven){ this.p = p; this.isEven = isEven; } @Override public void run() { int i = (isEven==true) ? 2 : 1; while(i < 10 ){ if(isEven){ p.printEven(i); }else{ p.printOdd(i); } i=i+2; } } } class Printer{ boolean isEven = true; Lock lock = new ReentrantLock(); Condition condEven = lock.newCondition(); Condition condOdd = lock.newCondition(); public void printEven(int no){ lock.lock(); while(isEven==true){ try { condEven.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() +no); isEven = true; condOdd.signalAll(); lock.unlock(); } public void printOdd(int no){ lock.lock(); while(isEven==false){ try { condOdd.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() +no); isEven = false; condEven.signalAll(); lock.unlock(); } } в import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class EvenOddThreads { public static void main(String[] args) throws InterruptedException { Printer p = new Printer(); Thread oddThread = new Thread(new PrintThread(p,false),"Odd :"); Thread evenThread = new Thread(new PrintThread(p,true),"Even :"); oddThread.start(); evenThread.start(); } } class PrintThread implements Runnable{ Printer p; boolean isEven = false; PrintThread(Printer p, boolean isEven){ this.p = p; this.isEven = isEven; } @Override public void run() { int i = (isEven==true) ? 2 : 1; while(i < 10 ){ if(isEven){ p.printEven(i); }else{ p.printOdd(i); } i=i+2; } } } class Printer{ boolean isEven = true; Lock lock = new ReentrantLock(); Condition condEven = lock.newCondition(); Condition condOdd = lock.newCondition(); public void printEven(int no){ lock.lock(); while(isEven==true){ try { condEven.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() +no); isEven = true; condOdd.signalAll(); lock.unlock(); } public void printOdd(int no){ lock.lock(); while(isEven==false){ try { condOdd.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() +no); isEven = false; condEven.signalAll(); lock.unlock(); } } 

Класс для печати нечетных Четное число

 public class PrintOddEven implements Runnable { private int max; private int number; public PrintOddEven(int max_number,int number) { max = max_number; this.number = number; } @Override public void run() { while(number<=max) { if(Thread.currentThread().getName().equalsIgnoreCase("odd")) { try { printOdd(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { try { printEven(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public synchronized void printOdd() throws InterruptedException { if(number%2==0) { wait(); } System.out.println(number+Thread.currentThread().getName()); number++; notifyAll(); } public synchronized void printEven() throws InterruptedException { if(number%2!=0) { wait(); } System.out.println(number+Thread.currentThread().getName()); number++; notifyAll(); } } в public class PrintOddEven implements Runnable { private int max; private int number; public PrintOddEven(int max_number,int number) { max = max_number; this.number = number; } @Override public void run() { while(number<=max) { if(Thread.currentThread().getName().equalsIgnoreCase("odd")) { try { printOdd(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { try { printEven(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public synchronized void printOdd() throws InterruptedException { if(number%2==0) { wait(); } System.out.println(number+Thread.currentThread().getName()); number++; notifyAll(); } public synchronized void printEven() throws InterruptedException { if(number%2!=0) { wait(); } System.out.println(number+Thread.currentThread().getName()); number++; notifyAll(); } } 

Программа драйверов

 public class OddEvenThread { public static void main(String[] args) { PrintOddEven printer = new PrintOddEven(10,1); Thread thread1 = new Thread(printer,"odd"); Thread thread2 = new Thread (printer,"even"); thread1.start(); thread2.start(); } } 

public class Solution {

  static class NumberGenerator{ private static volatile boolean printEvenNumber = false; public void printEvenNumber(int i) { synchronized (this) { if(!printEvenNumber) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(i); printEvenNumber = !printEvenNumber; notify(); } } public void printOddNumber(int i ) { synchronized (this) { if(printEvenNumber) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(i); printEvenNumber = !printEvenNumber; notify(); } } } static class OddNumberGenerator implements Runnable{ private NumberGenerator numberGenerator; public OddNumberGenerator(NumberGenerator numberGenerator) { this.numberGenerator = numberGenerator; } @Override public void run() { for(int i = 1; i <100; i = i + 2) { numberGenerator.printOddNumber(i); } } } static class EvenNumberGenerator implements Runnable { private NumberGenerator numberGenerator; public EvenNumberGenerator(NumberGenerator numberGenerator) { this.numberGenerator = numberGenerator; } @Override public void run() { for (int i = 2; i <= 100; i = i + 2) { numberGenerator.printEvenNumber(i); } } } public static void main(String[] args) { NumberGenerator ng = new NumberGenerator(); OddNumberGenerator oddNumberGenerator = new OddNumberGenerator(ng); EvenNumberGenerator evenNumberGenerator = new EvenNumberGenerator(ng); new Thread(oddNumberGenerator).start(); new Thread(evenNumberGenerator).start(); } 

}

 public class ThreadEvenOdd { static int cnt=0; public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { synchronized(this) { while(cnt<101) { if(cnt%2==0) { System.out.print(cnt+" "); cnt++; } notifyAll(); } } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { synchronized(this) { while(cnt<101) { if(cnt%2==1) { System.out.print(cnt+" "); cnt++; } notifyAll(); } } } }); t1.start(); t2.start(); } } 
  public class OddAndEvenThreadProblems { private static Integer i = 0; public static void main(String[] args) { new EvenClass().start(); new OddClass().start(); } public static class EvenClass extends Thread { public void run() { while (i < 10) { synchronized (i) { if (i % 2 == 0 ) { try { Thread.sleep(1000); System.out.println(" EvenClass " + i); i = i + 1; } catch (Exception e) { e.printStackTrace(); } } } } } } public static class OddClass extends Thread { @Override public void run() { while (i < 10) { synchronized (i) { if (i % 2 == 1) { try { Thread.sleep(1000); System.out.println(" OddClass " + i); i = i + 1; } catch (Exception e) { e.printStackTrace(); } } } } } } } OUTPUT will be :- EvenClass 0 OddClass 1 EvenClass 2 OddClass 3 EvenClass 4 OddClass 5 EvenClass 6 OddClass 7 EvenClass 8 OddClass 9 
 package programs.multithreading; public class PrintOddEvenNoInSequence { final int upto; final PrintOddEvenNoInSequence obj; volatile boolean oddFlag,evenFlag; public PrintOddEvenNoInSequence(int upto){ this.upto = upto; obj = this; oddFlag = true; evenFlag = false; } void printInSequence(){ Thread odd = new Thread(new Runnable() { @Override public void run() { for(int i = 1; i <= upto; i = i + 2){ synchronized (obj) { while(!oddFlag){ try { obj.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("Odd:"+i); oddFlag = false; evenFlag = true; obj.notify(); } } } }); Thread even = new Thread(new Runnable() { @Override public void run() { for(int i = 2; i <= upto; i = i + 2){ synchronized (obj) { while(!evenFlag){ try { obj.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("Even:"+i); oddFlag = true; evenFlag = false; obj.notify(); } } } }); odd.start(); even.start(); } public static void main(String[] args) { new PrintOddEvenNoInSequence(100).printInSequence(); } } в package programs.multithreading; public class PrintOddEvenNoInSequence { final int upto; final PrintOddEvenNoInSequence obj; volatile boolean oddFlag,evenFlag; public PrintOddEvenNoInSequence(int upto){ this.upto = upto; obj = this; oddFlag = true; evenFlag = false; } void printInSequence(){ Thread odd = new Thread(new Runnable() { @Override public void run() { for(int i = 1; i <= upto; i = i + 2){ synchronized (obj) { while(!oddFlag){ try { obj.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("Odd:"+i); oddFlag = false; evenFlag = true; obj.notify(); } } } }); Thread even = new Thread(new Runnable() { @Override public void run() { for(int i = 2; i <= upto; i = i + 2){ synchronized (obj) { while(!evenFlag){ try { obj.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("Even:"+i); oddFlag = true; evenFlag = false; obj.notify(); } } } }); odd.start(); even.start(); } public static void main(String[] args) { new PrintOddEvenNoInSequence(100).printInSequence(); } } в package programs.multithreading; public class PrintOddEvenNoInSequence { final int upto; final PrintOddEvenNoInSequence obj; volatile boolean oddFlag,evenFlag; public PrintOddEvenNoInSequence(int upto){ this.upto = upto; obj = this; oddFlag = true; evenFlag = false; } void printInSequence(){ Thread odd = new Thread(new Runnable() { @Override public void run() { for(int i = 1; i <= upto; i = i + 2){ synchronized (obj) { while(!oddFlag){ try { obj.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("Odd:"+i); oddFlag = false; evenFlag = true; obj.notify(); } } } }); Thread even = new Thread(new Runnable() { @Override public void run() { for(int i = 2; i <= upto; i = i + 2){ synchronized (obj) { while(!evenFlag){ try { obj.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("Even:"+i); oddFlag = true; evenFlag = false; obj.notify(); } } } }); odd.start(); even.start(); } public static void main(String[] args) { new PrintOddEvenNoInSequence(100).printInSequence(); } } 
 package example; public class PrintSeqTwoThreads { public static void main(String[] args) { final Object mutex = new Object(); Thread t1 = new Thread() { @Override public void run() { for (int j = 0; j < 10;) { synchronized (mutex) { System.out.println(Thread.currentThread().getName() + " " + j); j = j + 2; mutex.notify(); try { mutex.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; Thread t2 = new Thread() { @Override public void run() { for (int j = 1; j < 10;) { synchronized (mutex) { System.out.println(Thread.currentThread().getName() + " " + j); j = j + 2; mutex.notify(); try { mutex.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; t1.start(); t2.start(); } } 

Используйте следующий код, чтобы печатать нечетные и четные номера в правильном порядке вместе с желаемыми сообщениями.

 package practice; class Test { private static boolean oddFlag = true; int count = 1; private void oddPrinter() { synchronized (this) { while(true) { try { if(count < 10) { if(oddFlag) { Thread.sleep(500); System.out.println(Thread.currentThread().getName() + ": " + count++); oddFlag = !oddFlag; notifyAll(); } else { wait(); } } else { System.out.println("Odd Thread finished"); notify(); break; } } catch (InterruptedException e) { e.printStackTrace(); } } } } private void evenPrinter() { synchronized (this) { while (true) { try { if(count < 10) { if(!oddFlag) { Thread.sleep(500); System.out.println(Thread.currentThread().getName() + ": " + count++); oddFlag = !oddFlag; notify(); } else { wait(); } } else { System.out.println("Even Thread finished"); notify(); break; } } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws InterruptedException{ final Test test = new Test(); Thread t1 = new Thread(new Runnable() { public void run() { test.oddPrinter(); } }, "Thread 1"); Thread t2 = new Thread(new Runnable() { public void run() { test.evenPrinter(); } }, "Thread 2"); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println("Main thread finished"); } } 

Я не мог понять большинство кодов, которые были здесь, поэтому я написал себе один, возможно, это помогает кому-то вроде меня:

ПРИМЕЧАНИЕ. Это не использует отдельный режим печати и нечетный. Один метод print () делает все.

 public class test { private static int START_INT = 1; private static int STOP_INT = 10; private static String THREAD_1 = "Thread A"; private static String THREAD_2 = "Thread B"; public static void main(String[] args) { SynchronizedRepository syncRep = new SynchronizedRepository(START_INT,STOP_INT); Runnable r1 = new EvenOddWorker(THREAD_1,syncRep); Runnable r2 = new EvenOddWorker(THREAD_2,syncRep); Thread t1 = new Thread(r1, THREAD_1); Thread t2 = new Thread(r2, THREAD_2); t1.start(); t2.start(); } } public class SynchronizedRepository { private volatile int number; private volatile boolean isSlotEven; private int startNumber; private int stopNumber; public SynchronizedRepository(int startNumber, int stopNumber) { super(); this.number = startNumber; this.isSlotEven = startNumber%2==0; this.startNumber = startNumber; this.stopNumber = stopNumber; } public synchronized void print(String threadName) { try { for(int i=startNumber; i<=stopNumber/2; i++){ if ((isSlotEven && number % 2 == 0)|| (!isSlotEven && number % 2 != 0)){ System.out.println(threadName + " "+ number); isSlotEven = !isSlotEven; number++; } notifyAll(); wait(); } notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } } public class EvenOddWorker implements Runnable { private String threadName; private SynchronizedRepository syncRep; public EvenOddWorker(String threadName, SynchronizedRepository syncRep) { super(); this.threadName = threadName; this.syncRep = syncRep; } @Override public void run() { syncRep.print(threadName); } } 

Простое решение 🙂

 package com.code.threads; public class PrintOddEven extends Thread { private Object lock; static volatile int count = 1; PrintOddEven(Object lock) { this.lock = lock; } @Override public void run () { while(count <= 10) { if (count % 2 == 0) { synchronized(lock){ System.out.println("Even - " + count); ++count; try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } else { synchronized(lock){ System.out.println("Odd - " + count); ++count; lock.notify(); } } } } public static void main(String[] args) { Object obj = new Object(); PrintOddEven even = new PrintOddEven(obj); PrintOddEven odd = new PrintOddEven(obj); even.start(); odd.start(); } } 
 public class Main { public static void main(String[] args) throws Exception{ int N = 100; PrintingThread oddNumberThread = new PrintingThread(N - 1); PrintingThread evenNumberThread = new PrintingThread(N); oddNumberThread.start(); // make sure that even thread only start after odd thread while (!evenNumberThread.isAlive()) { if(oddNumberThread.isAlive()) { evenNumberThread.start(); } else { Thread.sleep(100); } } } } class PrintingThread extends Thread { private static final Object object = new Object(); // lock for both threads final int N; // N determines whether given thread is even or odd PrintingThread(int N) { this.N = N; } @Override public void run() { synchronized (object) { int start = N % 2 == 0 ? 2 : 1; // if N is odd start from 1 else start from 0 for (int i = start; i <= N; i = i + 2) { System.out.println(i); try { object.notify(); // will notify waiting thread object.wait(); // will make current thread wait } catch (InterruptedException e) { e.printStackTrace(); } } } } } 

Простое решение: –

 package com.test; class MyThread implements Runnable{ @Override public void run() { int i=1; while(true) { String name=Thread.currentThread().getName(); if(name.equals("task1") && i%2!=0) { System.out.println(name+"::::"+i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }else if(name.equals("task2") && i%2==0){ System.out.println(name+"::::"+i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } i++; } } public static void main(String[] args) { MyThread task1=new MyThread(); MyThread task2=new MyThread(); Thread t1=new Thread(task1,"task1"); Thread t2=new Thread(task2,"task2"); t1.start(); t2.start(); } } 
  • Ожидание выполнения нескольких streamов в Java
  • Почему не логично синхронизировать логику?
  • Как @synchronized блокировка / разблокировка в Objective-C?
  • Лучший инструмент для синхронизации баз данных MySQL
  • C ++ 0x не имеет семафоров? Как синхронизировать streamи?
  • Когда следует использовать спин-блокировку вместо мьютекса?
  • Как определить, заблокирован ли объект (синхронизирован), чтобы он не блокировался на Java?
  • Как использовать семафоры между процессами с использованием общей памяти
  • Синхронизированный блок Java для .class
  • В чем разница между атомными / летучими / синхронизированными?
  • Java Singleton и синхронизация
  • Давайте будем гением компьютера.