Example: Use condition variables in Java programs

This example shows a Java™ program using condition variables in the form of the wait and notify methods on a Java object. Note the locking protocol used.

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.
/*
FileName: ATEST18.java
The output of this example is as follows:
 Entered the testcase
 Create/start the thread
 Consumer Thread-1: Entered
 Consumer Thread-1: Wait for the data to be produced
 Producer: 'Finding data
 Consumer Thread-2: Entered
 Consumer Thread-2: Wait for the data to be produced
 Producer: Make data shared and notify consumer
 Producer: Unlock shared data and flag
 Consumer Thread-2: Found data or notified, CONSUME IT while holding inside the monitor
 Consumer Thread-2: Wait for the data to be produced
 Producer: 'Finding data
 Producer: Make data shared and notify consumer
 Producer: Unlock shared data and flag
 Producer: 'Finding data
 Consumer Thread-2: Found data or notified, CONSUME IT while holding inside the monitor
 Consumer Thread-2: All done
 Producer: Make data shared and notify consumer
 Producer: Unlock shared data and flag
 Producer: 'Finding data
 Consumer Thread-1: Found data or notified, CONSUME IT while holding inside the monitor
 Consumer Thread-1: Wait for the data to be produced
 Producer: Make data shared and notify consumer
 Producer: Unlock shared data and flag
 Wait for the threads to complete
 Consumer Thread-1: Found data or notified, CONSUME IT while holding inside the monitor
 Consumer Thread-1: All done
 Testcase completed
*/
import java.lang.*;
 
/* This class is an encapsulation of the condition variable plus */
/* mutex locking logic that can be seen in the Pthread example   */
class theSharedData extends Object {
   int                     dataPresent;
   int                     sharedData;
 
   public theSharedData() {
      dataPresent=0;
      sharedData=0;
   }
   public synchronized void get() {
      while (dataPresent == 0) {
         try {
            System.out.print("Consumer " +
                             Thread.currentThread().getName() +
                             ": Wait for the data to be produced\n");
            wait();
         }
         catch (InterruptedException e) {
            System.out.print("Consumer " +
                             Thread.currentThread().getName() +
                             ": wait interrupted\n");
         }
      }
      System.out.print("Consumer " +
                       Thread.currentThread().getName() +
                       ": Found data or notified, CONSUME IT " +
                       "while holding inside the monitor\n");
      --sharedData;
      if (sharedData == 0) {dataPresent=0;}
      /* in a real world application, the actual data would be returned */
      /* here                                                           */
   }
   public synchronized void put() {
      System.out.print("Producer: Make data shared and notify consumer\n");
      ++sharedData;
      dataPresent=1;
      notify();
      System.out.print("Producer: Unlock shared data and flag\n");
      /* unlock occurs when leaving the synchronized method */
   }
}
 
 
public class ATEST18 {
   public final static int NUMTHREADS   = 2;
   public static theSharedData dataConditionEncapsulation = new theSharedData();
 
   static class theThread extends Thread {
      public void run() {
         int      retries=2;
 
         System.out.print("Consumer " + getName() + ": Entered\n");
         while (retries-- != 0) {
            dataConditionEncapsulation.get();
            /* Typically an application would process the data outside */
            /* the monitor (synchronized get method here)              */
         }
         System.out.print("Consumer " + getName() + ": All done\n");
      }
   }
 
   public static void main(String argv[]) {
      int            amountOfData = 4;
      theThread threads[] = new theThread[NUMTHREADS];
      System.out.print("Entered the testcase\n");
 
      System.out.print("Create/start the thread\n");
      for (int i=0; i <NUMTHREADS; ++i) {
threads[i] = new theThread();
         threads[i].start();
      }
 
      while (amountOfData-- != 0) {
         System.out.print("Producer: 'Finding data\n");
         try {
            Thread.sleep(3000);
         }
         catch (InterruptedException e) {
            System.out.print("sleep interrupted\n");
         }
         dataConditionEncapsulation.put();
      }
 
      System.out.print("Wait for the threads to complete\n");
      for(int i=0; i <NUMTHREADS; ++i) {
  try {
            threads[i].join();
         }
         catch (InterruptedException e) {
            System.out.print("Join interrupted\n");
         }
      }
 
      System.out.print("Testcase completed\n");
      System.exit(0);
   }
}