Java Thread synchronized code with conditions

Introduction

Java has the wait(), notify(), and notifyAll() methods implemented in the Object class to handle conditioned synchronized code.

A thread can call the wait() method inside a synchronized block of code.

If it calls the wait() method outside a synchronized block of code, the JVM throws an IllegalMonitorStateException exception.

When the thread calls the wait() method, the JVM puts the thread to sleep and releases the object that controls the synchronized code.

In this way JVM allows the other threads to execute other blocks of synchronized code.

To wake up the thread, call the notify() or notifyAll() method.

The following code shows how to implement the producer-consumer problem using the synchronized keyword and the wait(), notify(), and notifyAll() methods.

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

public class Main {
  public static void main(String[] args) {
    SharedResource storage = new SharedResource();

    // Creates a Producer and a Thread to run it
    Producer producer = new Producer(storage);
    Thread thread1 = new Thread(producer);

    // Creates a Consumer and a Thread to run it
    Consumer consumer = new Consumer(storage);
    Thread thread2 = new Thread(consumer);

    // Starts the thread
    thread2.start();/*from  w w  w  . j a  v a2  s .co m*/
    thread1.start();
  }

}
class SharedResource {
  private int maxSize;
  private List<Date> storage;

  public SharedResource() {
    maxSize = 10;
    storage = new LinkedList<>();
  }

  // creates and storage an event.
  public synchronized void set() {
    while (storage.size() == maxSize) {
      try {
        wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    storage.add(new Date());
    System.out.printf("Set: %d", storage.size());
    notify();
  }

  // This method delete the first event of the storage.
  public synchronized void get() {
    while (storage.size() == 0) {
      try {
        wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    System.out.printf("Get: %d: %s", storage.size(), ((LinkedList<?>) storage).poll());
    notify();
  }

}
class Consumer implements Runnable {
  private SharedResource storage;

  public Consumer(SharedResource storage) {
    this.storage = storage;
  }

  @Override
  public void run() {
    for (int i = 0; i < 100; i++) {
      storage.get();
    }
  }

}
class Producer implements Runnable {
  private SharedResource storage;

  public Producer(SharedResource storage) {
    this.storage = storage;
  }

  @Override
  public void run() {
    for (int i = 0; i < 100; i++) {
      storage.set();
    }
  }
}



PreviousNext

Related