web-dev-qa-db-fra.com

Créez deux threads, un affichage impair et autres nombres pairs

J'essaie de créer deux threads, un thread affiche même des nombres entiers de 0 à 10, un thread affiche des nombres entiers impairs de 1 à 11. Le code suivant convient-il à la conception de ce programme?

public class Mythread {

    public static void main(String[] args) {
        Runnable r = new Runnable1();
        Thread t = new Thread(r);
        t.start();
        Runnable r2 = new Runnable2();
        Thread t2 = new Thread(r2);
        t2.start();
    }
}

class Runnable2 implements Runnable{
    public void run(){
        for(int i=0;i<11;i++){
            if(i%2 == 1)
                System.out.println(i);
        }
    }
}

class Runnable1 implements Runnable{
    public void run(){
        for(int i=0;i<11;i++){
            if(i%2 == 0)
                System.out.println(i);
        }
    }
}
19
Bernard

Je voudrais juste changer quelques détails (pas besoin d'utiliser l'opérateur modulo ici ...):

public class Mythread {

    public static void main(String[] args) {
        Runnable r = new Runnable1();
        Thread t = new Thread(r);
        Runnable r2 = new Runnable2();
        Thread t2 = new Thread(r2);
        t.start();
        t2.start();
    }
}

class Runnable2 implements Runnable{
    public void run(){
        for(int i=0;i<11;i+=2) {
            System.out.println(i);
        }
    }
}

class Runnable1 implements Runnable{
    public void run(){
        for(int i=1;i<=11;i+=2) {
           System.out.println(i);
        }
    }
}
13
aymeric

@aymeric answer n'imprimera pas les nombres dans leur ordre naturel, mais ce code le sera. Explication à la fin.

public class Driver {
    static Object lock = new Object();

    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            public void run() {

                for (int itr = 1; itr < 51; itr = itr + 2) {
                    synchronized (lock) {
                        System.out.print(" " + itr);
                        try {
                            lock.notify();
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            public void run() {

                for (int itr = 2; itr < 51; itr = itr + 2) {
                    synchronized (lock) {
                        System.out.print(" " + itr);
                        try {
                            lock.notify();
                            if(itr==50)
                                break;
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        try {
            t1.start();
            t2.start();
            t1.join();
            t2.join();
            System.out.println("\nPrinting over");
        } catch (Exception e) {

        }
    }
}

Afin d’y parvenir, les méthodes d’exécution des deux threads ci-dessus doivent être appelées les unes après les autres, c’est-à-dire qu’elles doivent être synchronisées et que je parviens à cela avec des verrous. 

Le code fonctionne comme suit: t1.run affiche le nombre impair et informe tout thread en attente qu'il va libérer le verrou, puis passe en état d'attente.

À ce stade, t2.run est appelé, il affiche le numéro pair suivant, informe les autres threads qu'il est sur le point de libérer le verrou qu'il détient, puis passe à l'état d'attente.

Cela continue jusqu'à ce que l'itr dans t2.run () atteigne 50. À ce stade, notre objectif est atteint et nous devons éliminer ces deux threads. 

En cassant, j'évite d'appeler lock.wait () dans t2.run et le thread t2 est donc arrêté, le contrôle passe maintenant à t1.run puisqu'il attendait l'acquisition du verrou; mais ici, sa valeur sera> 51 et nous sortirons de sa course (), fermant ainsi le fil. 

Si break n'est pas utilisé dans t2.run (), nous verrons les numéros 1 à 50 à l'écran, mais les deux threads entreront dans une situation de blocage et resteront en attente.

39
Rahul Prasad
package javaapplication45;

public class JavaApplication45 extends Thread {

    public static void main(String[] args) {
        //even numbers
        Thread t1 = new Thread() {
            public void run() {
                for (int i = 1; i <= 20; i++) {
                    if (i % 2 == 0) {
                        System.out.println("even thread " + i);
                    }
                }
            }
        };
        t1.start();
        //odd numbers
        Thread t2 = new Thread() {
            public void run() {
                for (int i = 1; i <= 20; i++) {
                    if (i % 2 != 0) {
                        System.out.println("odd thread " + i);
                    }
                }
            }
        };
        t2.start();

    }

}
3
laish138

Vous trouverez ci-dessous le code qui utilise le verrouillage sur un objet partagé portant le numéro à imprimer. Cela garantit également la séquence contrairement à la solution ci-dessus.

public class MultiThreadPrintNumber {
  int i = 1;

  public synchronized void printNumber(String threadNm) throws InterruptedException{

      if(threadNm.equals("t1")){
        if(i%2 == 1){
          System.out.println(Thread.currentThread().getName()+"--"+ i++);
          notify();
        } else {
          wait();
        }
      } else if(threadNm.equals("t2")){
        if(i%2 == 0){
          System.out.println(Thread.currentThread().getName()+"--"+ i++);
          notify();
        } else {
          wait();
        }
      }

    }

  public static void main(String[] args) {
    final MultiThreadPrintNumber obj = new MultiThreadPrintNumber();
    Thread t1 = new Thread(new Runnable() {

      @Override
      public void run() {
        try {
          while(obj.i <= 10){

            obj.printNumber(Thread.currentThread().getName());
          }
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        System.out.println("done t1");
      }
    });
    Thread t2 = new Thread(new Runnable() {

      @Override
      public void run() {
        try {
          while(obj.i <=10){
            obj.printNumber(Thread.currentThread().getName());
          }
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        System.out.println("done t2");
      }
    });

    t1.setName("t1");
    t2.setName("t2");
    t1.start();
    t2.start();
  }
}

La sortie ressemblera à ceci: T1--1 T2--2 T1–3 T2–4 T1–5 .t1-7 t2--8 t1--9 t2--10 fait t2 fait t1

3
adhirohah

Oui c'est bon. Mais dans ce cas, je ne pense pas que vous ayez besoin de 2 threads, car l’opération est simple. Cependant, si vous pratiquez des discussions, tout va bien.

3
PeakGen

Forfait simultané:

    import Java.util.concurrent.ExecutorService;

    import Java.util.concurrent.Executors;
    import Java.util.concurrent.Future;
    import Java.util.concurrent.locks.Condition;
    import Java.util.concurrent.locks.Lock;
    import Java.util.concurrent.locks.ReentrantLock;
    //=========== Task1 class prints odd =====
    class TaskClass1 implements Runnable
    {

    private Condition condition;
    private Lock lock;
    boolean exit = false;
    int i;
    TaskClass1(Condition condition,Lock lock)
    {
        this.condition = condition;
        this.lock = lock;
    }
    @Override
    public void run() {
        try
        {
            lock.lock();
            for(i = 1;i<11;i++)
            {
                if(i%2 == 0)
                {
                    condition.signal();
                    condition.await();

                }
                if(i%2 != 0)
                {
                    System.out.println(Thread.currentThread().getName()+" == "+i);

                }

            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally
        {
            lock.unlock();
        }

    }

}
//==== Task2 : prints even =======
class TaskClass2 implements Runnable
{

    private Condition condition;
    private Lock lock;
    boolean exit = false;
    TaskClass2(Condition condition,Lock lock)
    {
        this.condition = condition;
        this.lock = lock;
    }
    @Override
    public void run() {
        int i;
        // TODO Auto-generated method stub
        try
        {
            lock.lock();
            for(i = 2;i<11;i++)

            {

                if(i%2 != 0)
                {
                    condition.signal();
                    condition.await();
                }
                if(i%2 == 0)
                {
                    System.out.println(Thread.currentThread().getName()+" == "+i);

                }

            }

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally
        {
            lock.unlock();

        }

    }

}
public class OddEven {

    public static void main(String[] a)
    {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        Future future1;
        Future future2;
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        future1 = executorService.submit(new TaskClass1(condition,lock));
        future2 = executorService.submit(new TaskClass2(condition,lock));
        executorService.shutdown();


    }


}
1
AKumar

Je voudrais aussi envisager d’utiliser Java Concurrency si vous souhaitez des alternatives. Certaines des fonctionnalités fournies dans le package Java Concurrency offrent un niveau d'abstraction plus élevé que l'utilisation de la classe Thread directement et fournissent ainsi davantage de fonctionnalités.

Dans votre cas particulier, ce que vous faites est tout à fait raisonnable mais l’ordre d’impression de ces chiffres est-il important? Voulez-vous un peu avant les cotes? Ce genre de questions indiquerait mieux la conception qui répond le mieux à vos besoins.

1
ramsinb

Pas la réponse pour le problème ci-dessus mais sur les lignes similaires.

Programme pour imprimer les éléments du tableau de manière séquentielle mais utiliser deux threads différents pour imprimer les éléments adjacents

import Java.util.logging.Level;
import Java.util.logging.Logger;

/**
 *
 * @author ntv
 */
public class PrintLAternateNumber {
    public static void main(String[] args) {
        int [] num = {1,2,3,4,5,6};
        Printer p = new Printer();
        Thread t1 = new Thread(new Thread1(num,  p), "Thread1");
        Thread t2 = new Thread(new Thread2(num,  p), "Thread2");
        t1.start();
        t2.start();
    }


}

class Thread1 implements Runnable {
    int [] num;
    Printer p ;
    public Thread1(int[] num,  Printer p) {
        this.num = num;
        this.p = p;
    }

    public void run() {
        try {
            print();
        } catch (InterruptedException ex) {
            Logger.getLogger(Thread1.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void print() throws InterruptedException {
        int i = 1;

            while(i < num.length) {
                synchronized(num) {
                    while (p.evenPrinted) {
                        num.wait();
                     }
                }   

                synchronized(num) {
                     p.printEven(Thread.currentThread().getName(), num[i]);
                     i= i + 2;
                     num.notifyAll();

                }
            }
    }
}


class Thread2 implements Runnable {
    int [] num;
    Printer p ;
    public Thread2(int[] num, Printer p) {
        this.num = num;
        this.p = p;
    }

    public void run() {
        try {
            print();
        } catch (InterruptedException ex) {
            Logger.getLogger(Thread2.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void print() throws InterruptedException {
        int i = 0;

            while(i < num.length) {
                synchronized(num) {
                    while (!p.evenPrinted) {
                        num.wait();
                     }
                }    

                 synchronized(num) {
                     p.printOdd(Thread.currentThread().getName(), num[i]);
                     i = i + 2;
                     num.notifyAll();

                }
            }
    }
}

class Printer {
    boolean evenPrinted = true;
    void printEven(String threadName , int i) {
        System.out.println(threadName + "," + i);
        evenPrinted = true;
    }


        void printOdd(String threadName , int i) {
        System.out.println(threadName + "," + i);
        evenPrinted = false;
    }
}
1
nantitv
package thread;

import org.hibernate.annotations.Synchronize;

class PrintOdd implements Runnable {
    int count = -1;
    private Object common;

    PrintOdd(Object common) {
        this.common = common;
    }

    @Override
    public void run() {
        synchronized (common) {
            while (count < 1000) {
                try {
                    common.notifyAll();
                    System.out.println(count += 2);
                    common.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }

}

class PrintEven implements Runnable {

    int count = 0;
    private Object common;

    PrintEven(Object common) {
        this.common = common;
    }

    @Override
    public void run() {
        synchronized (common) {
            while (count < 1000) {
                try {
                    common.notifyAll();
                    System.out.println(count += 2);
                    common.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }

}

public class PrintNatural {
    public static void main(String args[]) {
        Object obj = new Object();
        Runnable r = new PrintOdd(obj);
        Thread printOdd = new Thread(r);

        Runnable r2 = new PrintEven(obj);
        Thread printEven = new Thread(r2);

        printOdd.start();
        printEven.start();

    }

}
1
Aayush Singhal

Nos numéros seront imprimés dans l'ordre

Main class
===========
package com.thread;

import Java.util.concurrent.atomic.AtomicInteger;

public class StartThread {
    static AtomicInteger no = new AtomicInteger(1);
    public static void main(String[] args) {
        Odd oddObj = new Odd();
        Thread odd = new Thread(oddObj);
        Thread even = new Thread(new Even(oddObj));
        odd.start();
        even.start();
    }
}

Odd Thread
===========
package com.thread;

public class Odd implements Runnable {

    @Override
    public void run() {
        while (StartThread.no.get() < 20) {
            synchronized (this) {
                System.out.println("Odd=>" + StartThread.no.get());
                StartThread.no.incrementAndGet();

                try {
                    this.notify();
                    if(StartThread.no.get() == 20)
                        break;
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

Even Thread
===========
package com.thread;

public class Even implements Runnable {
    Odd odd;

    public Even(Odd odd) {
        this.odd = odd;
    }

    @Override
    public void run() {
        while (StartThread.no.get() < 20) {
            synchronized (odd) {
                System.out.println("Even=>" + StartThread.no.get());
                StartThread.no.incrementAndGet();
                odd.notifyAll();
                try {
                    odd.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }       

    }

}

Output (Nos are printed in sequential)
======
Odd=>1
Even=>2
Odd=>3
Even=>4
Odd=>5
Even=>6
Odd=>7
Even=>8
Odd=>9
Even=>10
Odd=>11
Even=>12
Odd=>13
Even=>14
Odd=>15
Even=>16
Odd=>17
Even=>18
Odd=>19
1
Prasath Rajan
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();
    }
}
0
Sazid Ali
public class OddEvenPrinetr {
    private static Object printOdd = new Object();

    public static void main(String[] args) {

        Runnable oddPrinter =  new Runnable() {
            int count = 1;
            @Override
            public void run() {
                while(true){
                    synchronized (printOdd) {
                        if(count >= 101){
                            printOdd.notify();
                            return;
                        }
                        System.out.println(count);
                        count = count + 2;                                              
                        try {
                            printOdd.notify();
                            printOdd.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };


        Runnable evenPrinter =  new Runnable() {
            int count = 0;
            @Override
            public void run() {
                while(true){
                    synchronized (printOdd) {
                        printOdd.notify();
                        if(count >= 100){                       
                            return;
                        }                                       
                        count = count + 2;
                        System.out.println(count);
                        printOdd.notify();
                        try {
                            printOdd.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };

        new Thread(oddPrinter).start();
        new Thread(evenPrinter).start();
    }
}
0
Ajeet
public class ThreadExample {

Object lock = new Object();

class ThreadEven implements Runnable {

    @Override
    public void run() {
        int i = 2;
        while (i <= 20) {
            synchronized (lock) {
                System.out.println(i + " ");
                i = i + 2;
                lock.notify();
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

class ThreadOdd implements Runnable {

    @Override
    public void run() {
        int i = 1;
        while (i <= 20) {
            synchronized (lock) {
                System.out.println(i + " ");
                i = i + 2;
                try {
                    lock.notify();
                    lock.wait();
                } catch (InterruptedException e) {

                    e.printStackTrace();
                }
            }
        }

    }

}

public static void main(String args[]) {

    ThreadExample example = new ThreadExample();
    ThreadExample.ThreadOdd odd = example.new ThreadOdd();
    ThreadExample.ThreadEven even = example.new ThreadEven();

    Thread oT = new Thread(odd);
    Thread eT = new Thread(even);

    oT.start();
    eT.start();

}
0
Nayan

classe publique ConsecutiveNumberPrint {

private static class NumberGenerator {

    public int MAX = 100;

    private volatile boolean evenNumberPrinted = true;

    public NumberGenerator(int max) {
        this.MAX = max;
    }

    public void printEvenNumber(int i) throws InterruptedException {
        synchronized (this) {
            if (evenNumberPrinted) {
                wait();
            }
            System.out.println("e = \t" + i);
            evenNumberPrinted = !evenNumberPrinted;
            notify();
        }
    }

    public void printOddNumber(int i) throws InterruptedException {
        synchronized (this) {
            if (!evenNumberPrinted) {
                wait();
            }
            System.out.println("o = \t" + i);
            evenNumberPrinted = !evenNumberPrinted;
            notify();
        }
    }

}

private static class EvenNumberGenerator implements Runnable {

    private NumberGenerator numberGenerator;

    public EvenNumberGenerator(NumberGenerator numberGenerator) {
        this.numberGenerator = numberGenerator;
    }

    @Override
    public void run() {
        for(int i = 2; i <= numberGenerator.MAX; i+=2)
            try {
                numberGenerator.printEvenNumber(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }
}

private static class OddNumberGenerator implements Runnable {

    private NumberGenerator numberGenerator;

    public OddNumberGenerator(NumberGenerator numberGenerator) {
        this.numberGenerator = numberGenerator;
    }

    @Override
    public void run() {
        for(int i = 1; i <= numberGenerator.MAX; i+=2) {
            try {
                numberGenerator.printOddNumber(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public static void main(String[] args) {
    NumberGenerator numberGenerator = new NumberGenerator(100);
    EvenNumberGenerator evenNumberGenerator = new EvenNumberGenerator(numberGenerator);
    OddNumberGenerator oddNumberGenerator = new OddNumberGenerator(numberGenerator);
    new Thread(oddNumberGenerator).start();
    new Thread(evenNumberGenerator).start();

}

}

0
Victor

paquet p.Threads;

public class PrintEvenAndOddNum  {

    private  Object obj = new Object();

    private static final PrintEvenAndOddNum peon = new PrintEvenAndOddNum();

    private PrintEvenAndOddNum(){}

    public static PrintEvenAndOddNum getInstance(){
        return peon;
    }

    public  void printOddNum()  {
        for(int i=1;i<10;i++){
            if(i%2 != 0){
                synchronized (obj) {
                    System.out.println(i);

                    try {
                        System.out.println("oddNum going into waiting state ....");
                        obj.wait();

                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("resume....");
                    obj.notify();
                }
            }
        }
    }

    public  void printEvenNum()  {
        for(int i=1;i<11;i++){
            if(i%2 == 0){
                synchronized(obj){
                    System.out.println(i);
                    obj.notify();
                    try {
                        System.out.println("evenNum going into waiting state ....");
                        obj.wait();
                        System.out.println("Notifying waiting thread ....");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }   
}
0
Vikas naik
public class MyThread {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Threado o =new Threado();
        o.start();

        Threade e=new Threade();
        e.start();    
    }    
}


class Threade extends Thread{

    public void run(){

        for(int i=2;i<10;i=i+2)
            System.out.println("evens "+i);         
    }       
}


class Threado extends Thread{

    public void run(){

        for(int i=1;i<10;i=i+2)
            System.out.println("odds "+i);          
    }       
}

SORTIE: -

cotes 1 cotes 3 .__ cotes 5 cotes 7 cotes 9

0
saurabh prakash
public class EvenOddNumberPrintUsingTwoThreads {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Thread t1 = new Thread() {          
            public void run() {

                for (int i = 0; i <= 10; i++) {
                    if (i % 2 == 0) {
                        System.out.println("Even : " + i);
                    }
                }

            }
        };

        Thread t2 = new Thread() {
            // int i=0;
            public void run() {

                for (int i = 0; i <= 10; i++) {
                    if (i % 2 == 1) {
                        System.out.println("Odd : " + i);
                    }
                }

            }
        };
        t1.start();
        t2.start();
    }
}
0
yel
 public class ThreadClass {
   volatile int i = 1;
    volatile boolean state=true;

    synchronized public void printOddNumbers(){

                   try {
                       while (!state) {

                           wait();
                       }

                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                System.out.println(Thread.currentThread().getName()+" "+i);
                      state = false;
                      i++;
                      notifyAll();

    }

  synchronized  public void printEvenNumbers(){

      try {
          while (state) {

              wait();
          }

      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName()+" "+i);
      state = true;
      i++;
      notifyAll();

    }
}

Ensuite, appelez la classe ci-dessus comme ceci

   // I am ttying to print 10 values.
  ThreadClass threadClass=new ThreadClass();

        Thread t1=new Thread(){
            int k=0;
            @Override
            public void run() {
                while (k<5) {
                    threadClass.printOddNumbers();
                    k++;
                }
            }
        };
        t1.setName("Thread1");
        Thread t2=new Thread(){
            int j=0;
            @Override
            public void run() {
                while (j<5) {
                    threadClass.printEvenNumbers();
                    j++;
                }
            }
        };
        t2.setName("Thread2");

        t1.start();

        t2.start();
  1. Ici, j'essaie d'imprimer les 1 à 10 chiffres.
  2. Un fil essayant d'imprimer les nombres pairs et un autre nombre de fils impairs.
  3. ma logique est d'imprimer le nombre pair après le nombre impair. Pour cela, les fils pairs devraient attendre jusqu'à ce qu'ils soient notifiés par la méthode des nombres impairs.
  4. Chaque thread appelle une méthode particulière 5 fois parce que j'essaie d'imprimer 10 valeurs uniquement.

out mis: 

System.out: Thread1 1
System.out: Thread2 2
System.out: Thread1 3
System.out: Thread2 4
System.out: Thread1 5
System.out: Thread2 6
System.out: Thread1 7
System.out: Thread2 8
System.out: Thread1 9
System.out: Thread2 10
0
Kona Suresh

À peu près tout ce qui est nécessaire si vous êtes invité à imprimer des nombres pairs impairs de manière synchronisée.

public class ThreadingOddEvenNumbers {

    void main(String[] args) throws InterruptedException {
        Printer printer = new Printer(57);
        Thread t1 = new Thread(new MyRunner(printer, true), "EvenPrinter");
        Thread t2 = new Thread(new MyRunner(printer, false), "OddPrinter");
        t1.start();
        t2.start();

        t1.join();
        t2.join();
    }

}

class MyRunner implements Runnable {
    private Printer p;
    private boolean evenProperty;

    public MyRunner(Printer p, boolean evenNess) {
        this.p = p;
        evenProperty = evenNess;
    }

    public void run() {
        try {
            print();
        } catch (InterruptedException ex) {
            System.out.println(this.getClass().getName() + " "
                    + ex.getMessage());
        }
    }


    public void print() throws InterruptedException {
        while (!p.isJobComplete()) {
            synchronized (p) {
                if (evenProperty)
                    while (p.isEvenPrinted()) {
                        System.out.println("wait by: "
                                + Thread.currentThread().getName());
                        p.wait();
                        if (p.isJobComplete())
                            break;
                    }
                else
                    while (!p.isEvenPrinted()) {
                        System.out.println("wait by: "
                                + Thread.currentThread().getName());
                        p.wait();
                        if (p.isJobComplete())
                            break;
                    }
            }

            synchronized (p) {
                if (evenProperty)
                    p.printEven(Thread.currentThread().getName());
                else
                    p.printOdd(Thread.currentThread().getName());
                p.notifyAll();
                System.out.println("notify called: by: "
                        + Thread.currentThread().getName());
            }
        }
    }
}

class Printer {
    private volatile boolean evenPrinted;
    private volatile boolean jobComplete;
    private int limit;
    private int counter;

    public Printer(int lim) {
        limit = lim;
        counter = 1;
        evenPrinted = true;
        jobComplete = false;
    }

    public void printEven(String threadName) {
        System.out.println(threadName + "," + counter);
        incrCounter();
        evenPrinted = true;
    }

    public void printOdd(String threadName) {
        System.out.println(threadName + "," + counter);
        incrCounter();
        evenPrinted = false;
    }

    private void incrCounter() {
        counter++;
        if (counter >= limit)
            jobComplete = true;
    }

    public int getLimit() {
        return limit;
    }

    public boolean isEvenPrinted() {
        return evenPrinted;
    }

    public boolean isJobComplete() {
        return jobComplete;
    }
}
0
shashi