CIS 260 await and signal

We can add conditions to our locks and then use the await and signal methods to further control access to critical sections of code. The await and signal methods of Condition objects are similar in their use to the older wait and notify methods. The signal method, just like the notify method, wakes up a random thread that was waiting for the condition. There are also signalAll and notifyAll methods which wake up every waiting thread to see if any of them is ready to go forward. Signalling a single thread is much more efficient, but can lead to deadlock if it is not able to make progress.

import java.util.concurrent.locks.*;

public class TThreadAb {
    private static int[] pool = new int[100];
    private static int numItems = 0;
    private static long total = 0L;
    private static ReentrantLock lock = new ReentrantLock();
    private static Condition notFull = lock.newCondition();
    private static Condition notEmpty = lock.newCondition();
    private static boolean done = false;
    
    public static void main(String[] args) {
        TThreadAb app = new TThreadAb();
    }
    
    private TThreadAb() {
        Producer producer = new Producer();
        Consumer consumer = new Consumer();
        producer.start();
        consumer.start();
    }

    class Producer extends Thread {
        private int count = 0;
        public void run() {
            while (count < 20000) {
                lock.lock();
                try {
                    if (numItems == pool.length) notFull.await();
                    pool[numItems++] = ++count;
                    notEmpty.signal();
                } catch (InterruptedException e) {
                    System.err.println("Producer thread interrupted while waiting");
                } finally {
                    lock.unlock();
                }
            }
            done = true;
        }
    }

    class Consumer extends Thread {
        public void run() {
            while (!done || numItems > 0) {
                lock.lock();
                try {
                    if (numItems == 0) notEmpty.await();
                    total += pool[--numItems];
                    notFull.signal();
                } catch (InterruptedException e) {
                    System.err.println("Consumer thread interrupted while waiting");
                } finally {
                    lock.unlock();
                }
            }
            System.out.println("Total: " + total);
        }
    }
}

//   Total: 200010000

Previous: the notify method

Next: daemon threads