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