Java Reference
In-Depth Information
threads for that object and stops running. When another thread calls the noti
fyAll() method of the same object, the object wakes up the waiting threads and
allows them to continue running.
For example, let's look at a simplified version of a queue that is safe for multithrea‐
ded use:
/*
* One thread calls push() to put an object on the queue.
* Another calls pop() to get an object off the queue. If there is no
* data, pop() waits until there is some, using wait()/notify().
*/
public class WaitingQueue < E > {
LinkedList < E > q = new LinkedList < E >(); // storage
public synchronized void push ( E o ) {
q . add ( o ); // Append the object to the end of the list
this . notifyAll (); // Tell waiting threads that data is ready
}
public synchronized E pop () {
while ( q . size () == 0 ) {
try { this . wait (); }
catch ( InterruptedException ignore ) {}
}
return q . remove ();
}
}
This class uses a wait() on the instance of WaitingQueue if the queue is empty
(which would make the pop() fail). The waiting thread temporarily releases its
monitor, allowing another thread to claim it—a thread that might push() some‐
thing new onto the queue. When the original thread is woken up again, it is restar‐
ted where it originally began to wait—and it will have reacquired its monitor.
y
y d
wait() and notify() must be used inside a synchronized
method or block, because of the temporary relinquishing of
locks that is required for them to work properly.
In general, most developers shouldn't roll their own classes like the one in this
example—instead, make use of the libraries and components that the Java platform
provides for you.
Summary
In this chapter, we've discussed Java's view of memory and concurrency, and seen
how these topics are intrinsically linked. As processors develop more and more
cores, we will need to use concurrent programming techniques to make effective
use of those cores. Concurrency is key to the future of well-performing applications.
Search WWH ::




Custom Search