Locks

The java.util.concurrent.locks package provides interfaces and classes for locking and waiting.

This Lock interface provides more locking operations than the synchronized keyword. Lock supports a wait/notification mechanism through associated Condition objects.

Lock objects can back out of an attempt to acquire a lock. The tryLock() method backs out when the lock is not available immediately or when a timeout expires.

The lockInterruptibly() method backs out when another thread sends an interrupt before the lock is acquired.

ReentrantLock implements Lock, describing a reentrant mutual exclusion Lock implementation.

 
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Main {
  public static void main(String[] args) {
    final Lock lock = new ReentrantLock();
    final BlockingQueue<Character> bq;
    bq = new ArrayBlockingQueue<Character>(26);
    final ExecutorService executor = Executors.newFixedThreadPool(2);
    Runnable producer;
    producer = new Runnable() {
      public void run() {
        for (char ch = 'A'; ch <= 'F'; ch++) {
          try {
            lock.lock();
            try {
              while (!bq.offer(ch)) {
                lock.unlock();
                Thread.sleep(1000);
                lock.lock();
              }
              System.out.println(ch + " produced by producer.");
            } catch (InterruptedException ie) {
              assert false;
            }
          } finally {
            lock.unlock();
          }
        }
      }
    };
    executor.execute(producer);
    Runnable consumer;
    consumer = new Runnable() {
      public void run() {
        char ch = '\0';
        do {
          try {
            lock.lock();
            try {
              Character c;
              while ((c = bq.poll()) == null) {
                lock.unlock();
                Thread.sleep(1000);
                lock.lock();
              }
              ch = c;
              System.out.println(ch + " consumed by consumer.");
            } catch (InterruptedException ie) {
              assert false;
            }
          } finally {
            lock.unlock();
          }
        } while (ch != 'F');
        executor.shutdownNow();
      }
    };
    executor.execute(consumer);
  }
}