img
. .
Thread 1
Thread 2
public void frob() {
public void tweek() {
synchronized (one)
synchronized (two)
synchronized (two) {...}
synchronized (one) {...}
}
}
Figure 7-8. Typical Deadlock
Although typically a two-thread problem, deadlocks can involve dozens of threads in a circle, all
waiting for one another. They can involve a single thread that tries to obtain the same
(nonrecursive) mutex twice, and they can involve a thread that holds a lock dying while another
thread is waiting for it.
Deadlocks can always be avoided simply by using careful programming practices. If you declare a
lock hierarchy and always acquire locks in the same order--A before B before C, etc.--then there
is no chance of a deadlock. When you want to do out-of-order locking, you can use the trylock
functions to see whether you can get all the locks you need, and if not, then release them all and
try again later (Code Example 7-8).
Example 7-8 Locking Mutexes Out of Order
pthread_mutex_lock(&m2);
...
if (EBUSY == pthread_mutex_trylock(&m1)) {
pthread_mutex_unlock(&m2);
pthread_mutex_lock(&m1);
pthread_mutex_lock(&m2);
}
do_real_work();
/* Got 'em both! */
A typical instance of this out-of-order locking is the Solaris virtual memory system, which must
lock access to pages. There is an official hierarchy which says that page 1 must be locked before
page 2, etc. Occasionally, the VM system will lock page 2 and then discover that it also wants
page 1. It will then execute a trylock on page 1. If that succeeds, all is well and it proceeds. If it
fails, it releases the lock on page 2 and requests the locks in proper order.[3] This is a simple
optimization that saves a bit of time in the normal case and is always correct.
[3]
Note that you must release lock m2. Just spinning, waiting for m1 to become available, will not
work.
Search WWH :
Custom Search
Previous Page
Multithreaded Programming with JAVA - Topic Index
Next Page
Multithreaded Programming with JAVA - Bookmarks
Home