Imprimir pares e impares usando dos hilos en Java

Probé el código a continuación. Tomé este fragmento de código de otra publicación que es correcta según el autor. Pero cuando bash correr, no me da el resultado exacto.

Esto es principalmente para imprimir valores pares e impares en secuencia.

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(); } } 

¿Alguien puede ayudarme a arreglar esto?

EDITAR Resultado esperado: Impar: 1 Par: 2 Impar: 3 Par: 4 Impar: 5 Par: 6 Impar: 7 Par: 8 Impar: 9

Encontré la solución. Alguien que busque una solución a este problema puede referirse 🙂

 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(); } } 

Esto da salida como:

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

Aquí está el código que lo hice funcionar a través de una sola clase

 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(); } } } } } 

Salida:

 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(); } } 

Utilice esta siguiente característica muy simple de JAVA 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(); } } 

Lo mismo se puede hacer con la interfaz de locking:

 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(); } } 

Este código también funcionará bien.

 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(); } } 

La otra pregunta se cerró como un duplicado de esta. Creo que podemos deshacernos de forma segura del problema “par o impar” y usar el constructo de wait/notify siguiente manera:

 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(); } } 

Lo he hecho de esta manera, mientras imprimo usando dos hilos, no podemos predecir la secuencia que hilo
se ejecutará primero, así que para superar esta situación tenemos que sincronizar el recurso compartido, en
En mi caso, la función de impresión a la que intentan acceder dos hilos.

 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(); } } 

Esta es mi solución al problema. Tengo dos clases implementando Runnable , una imprime una secuencia impar y la otra imprime par. Tengo una instancia de Object , que uso para el locking. Inicializo las dos clases con el mismo objeto. Hay un synchronized block dentro del método de ejecución de las dos clases, donde, dentro de un bucle, cada método imprime uno de los números, notifica al otro, esperando el locking del mismo objeto y luego espera el mismo locking otra vez.

Las clases :

 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(); } } 

El límite superior en mi ejemplo es 10. Una vez que el hilo impar imprime 9 o el hilo par imprime 10, entonces no necesitamos que ninguno de los hilos espere más. Entonces, podemos manejar eso usando un if-block . O bien, podemos utilizar el método de wait(long timeout) sobrecargado wait(long timeout) para que se agote el tiempo de espera. Una falla aquí sin embargo. Con este código, no podemos garantizar qué hilo comenzará a ejecutarse primero.

Aquí está el código de trabajo para imprimir impares, incluso no alternativamente usando el mecanismo de esperar y notificar. He restringido el límite de números para imprimir de 1 a 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(); } } } } 

A continuación está mi implementación usando 2 semáforos.

  1. Semáforo impar con permiso 1.
  2. Incluso semáforo con permiso 0.
  3. Pase los dos semáforos a ambos hilos como la siguiente firma (mi, otro): –
  4. Al pase de hilo impar en el orden (impar, par)
  5. Para el paso de hilo Even en este orden (par, impar)
  6. La lógica del método run () es my.acquireUninterruptibly () -> Print -> other.release ()
  7. En el hilo Even ya que incluso Sema es 0 bloqueará.
  8. En el hilo impar como Sema impar está disponible (init en 1) esto imprimirá 1 y luego liberará incluso el Sema permitiendo que el hilo Even se ejecute.
  9. Incluso el hilo ejecuta impresiones 2 y suelta Sema impar permitiendo que se ejecute el hilo impar.

     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!!!"); } } 

Lo siguiente es la salida:

 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!!! 

Creo que las soluciones proporcionadas han agregado cosas innecesariamente y no usan semáforos en todo su potencial. Aquí está mi solución.

 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(); } } 

Solución de trabajo usando una sola clase

 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(); } } } } } } 

Puede usar el siguiente código para obtener la salida con la creación de dos clases de subprocesos anónimos.

 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(); } } 

Esto se puede lograr usando Bloqueo y condición:

 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(); } } 

Clase para imprimir impar Número par

 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(); } } 

Progtwig de manejo

 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(); } } 

Solución de clase pública {

  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 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(); } } 

Utilice el siguiente código para imprimir números impares y pares en el orden correcto junto con los mensajes deseados.

 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"); } } 

No pude entender la mayoría de los códigos que estaban aquí, así que me escribí uno, tal vez ayuda a alguien como yo:

NOTA: Esto no utiliza un método de impresión impar e impar. Un método print () lo hace todo.

 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); } } 

Solución simple 🙂

 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(); } } } } } 

Solución simple a continuación: –

 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(); } }