class Producer extends Thread { public void run() { for (int i = 0; i < 10; i++) { cubbyhole.put(i); System.out.println("Producer #" + this.number + " put: " + i); try { sleep((int)(Math.random() * 100)); } catch (InterruptedException e){} } } }
The Consumer consumes all integers from the CubbyHole as quickly as they become available.
class Consumer extends Thread { public void run() { int value = 0; for (int i = 0; i < 10; i++) { value = cubbyhole.get(); System.out.println("Consumer #" + this.number + " got: " + value); } } }
Producer is quicker than the Consumer:
. . . Consumer #1 got: 3 Producer #1 put: 4 Producer #1 put: 5 Consumer #1 got: 5 . . .
Consumer is quicker than the Producer:
. . . Producer #1 put: 4 Consumer #1 got: 4 Consumer #1 got: 4 Producer #1 put: 5 . . .
Definition: A monitor is associated with a specific data item and functions as a lock on that data.
When a thread holds the monitor for some data item, other threads are locked out and cannot inspect or modify the data.
A unique monitor is associated with every object that has a synchronized method.
class CubbyHole { private int contents; private boolean available = false; public synchronized int get() { while (available == false) { try { wait(); } catch (InterruptedException e) { } } available = false; notify(); return contents; } public synchronized void put(int value) { while (available == true) { try { wait(); } catch (InterruptedException e) { } } contents = value; available = true; notify(); } }
Lock: The thread that called a synchronized method acquires the monitor for the object whose method has been called.
Object state: No other threads can call a synchronized method on the same object.
Unlock: When the synchronized method returns, the thread releases the monitor thereby unlocking the object.
The wait() method causes the current thread to:
Wait until another thread notifies it of a condition change.
Release the monitor for the object.
public synchronized int get() { while (available == false) { try { wait(); // waits for notify() call from Producer } catch (InterruptedException e) { } } available = false; notify(); return contents; }
Other versions:
wait(long timeout) wait(long timeout, int nanos)
The notify() method chooses one thread that is waiting on the monitor held by the current thread and wakes it up.
![]() | Note |
---|---|
The Java runtime system makes no commitments or guarantees about which thread will be chosen. |
public synchronized int get() { while (available == false) { try { wait(); } catch (InterruptedException e) { } } available = false; notify(); // notifies Producer return contents; }
notifyAll():
It wakes up all the threads waiting on the same monitor.
The awakened threads compete for the monitor.
One thread gets the monitor and the others go back to waiting.
Copyright © 1998-2009 Dilvan Moreira