Java Threads 2

Thread Methods
Some of the common thread methods are listed below:
  • start()
  • sleep()
  • yield()
  • run()
  • wait()
  • notify()
  • notifyAll()
  • setPriority()

Thread Synchronization - Wait and Notify
Threads are based upon the concept of a Monitor. The wait() and notify() methods are used just like wait and signal in a Monitor. The following example of a producer-consumer problem elaborates the concept of thread synchronization and sharing objects between threads inside a single Java program:
class Buffer {
   private int [ ] buf;
   private int head, tail, max, size;

   public Buffer (int buf_size) {
      buf = new int [buf_size];
      head =0; tail = 0; size = 0;
      max = buf_size;
   }
              
   public synchronized void deposit (int item) {
      try {
         while (size ==max) wait();
                                buf [tail] = item;
                                tail = (tail + 1) % max;
                                size++;
                                notify();
                }
      catch
                    (interruptedException e) {
                                // exception handler
                }
   }

   public synchronized int fetch() {
      int item = 0;
                 try {
                               while (size == 0) wait();
                               item = buf [head] ;
                               head = (head + 1) % max;
                               size--;
                               notify();
                }
                catch (interruptedException e) {
                               // exception handler
                }
               return item;
   }
}

class Producer extends Thread {
   private Buffer buffer;

   public Producer (Buffer buf) {
      buffer = buf;
   }

   public void run () {
      int item;
      while (true) {
                              // create a new item
                               buffer.deposit(item);
                 }
  }
}

class Consumer implements Runnable  {
   private Buffer buffer;

   public Consumer (Buffer buf) {
      buffer = buf;
   }

   public void run () {
      int item;
      while (true) {
         item = buffer.fetch();
                                // consume item
                }
  }
}
We can now instantiate these threads as shown below:
Buffer buffer = new Buffer(100);
Producer producer1 = new Producer(buffer);
Consumer comsumer = new Consumer(buffer);
Thread consumer1 = new Thread(consumer);
producer1.start(); consumer1.start();

In this case the buffer is a shared variable used by both producer and consumer.

notify() and notifyAll()
There is a slight difference between notify() and notifyAll(). As the name suggest, notify() wakes up a single thread which is waiting on the object's lock. If there is more than one thread waiting, the choice is arbitrary i.e. there is no way to specify which waiting thread should be re-awakened. On the other hand, notifyAll() wakes up ALL waiting threads; the scheduler decides which one will run.