Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Programming Java threads in the real world, Part 2

The perils of race conditions, deadlock, and other threading problems

  • Print
  • Feedback

Page 2 of 7

To refine the earlier analogy, the airplane is still the object, but the monitor is really all the bathrooms combined (each synchronized chunk of code is a bathroom). When a thread enters any bathroom, the doors on all the bathrooms are locked. Different instances of a class are different airplanes, however, and if the bathroom doors in your airplane are unlocked, you needn't really care about the state of the doors in the other airplanes.

Why is stop() deprecated in JDK 1.2?

The fact that the monitor is built into every Java object is actually somewhat controversial. Some of the problems associated with bundling the condition variable and mutex together inside every Java object have been fixed in JDK 1.2, by the simple expediency of deprecating the most problematic methods of the Thread class: stop() and suspend(). You can deadlock a thread if you call either of these methods from inside a synchronized method of your own. Look at the following method, remembering that the mutex is the lock on the door, and the thread that locks the door "owns" the monitor. That's why the stop() and suspend() methods are deprecated in JDK 1.2. Consider this method:

class some_class
{   //...
    synchronized void f()
    {   Thread.currentThread().stop();
    }
}


Now consider what happens when a thread calls f(). The thread acquires the lock when entering the monitor but then stops. The mutex is not released by stop(). This is the equivalent of someone going into the bathroom, locking the door, and flushing himself down the toilet! Any other thread that now tries to call f() (or any other synchronized method of the class) on the same object is blocked forever. The suspend() method (which is also deprecated) has the same problem. The sleep() method (which is not deprecated) can be just as tricky. (Someone goes into the bathroom, locks the door, and falls asleep). Also remember that Java objects, even those that extend Thread or implement Runnable, continue to exist, even if the associated thread has stopped. You can indeed call a synchronized method on an object associated with a stopped thread. Be careful.

Race conditions and spin locks

A race condition occurs when two threads try to access the same object at the same time, and the behavior of the code changes depending on who wins. The following diagram shows a single (unsynchronized) object accessed simultaneously by multiple threads. A thread can be preempted in fred() after modifying one field but before modifying the other. If another thread comes along at that point and calls any of the methods shown, the object will be left in an unstable state, because the initial thread will eventually wake up and modify the other field.

Usually, you think of objects sending messages to other objects. In multithreaded environments, you must think about message handlers running on threads. Think: this thread causes this object to send a message to that object. A race condition can occur when two threads cause messages to be sent to the same object at the same time.

  • Print
  • Feedback

Resources
  • Sun's Technical Articles page has several articles on multithreading http://developer.javasoft.com/developer/technicalArticles/#thread
  • Prashant Jain and Douglas C. Schmidt have a good article contrasting C++ to Java that discusses many of the thread-related problems inherent in the language. The article can be found at http://www.cs.wustl.edu/%7Eschmidt/C++2java.html
  • Doug Lea has a bunch of Mutex and Condition-variable classes in his util.concurrent package. See http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html
  • Doug Schmidt's Ace Framework is a good, though complex, attempt at a truly platform-independent threading system http://www.cs.wustl.edu/~schmidt/
  • There are several good books that discuss the Java threading issues mentioned in the first article in this series. For convenience, I've listed them again here:
  • For a great in-depth look at multithreading in general and the implementation of multithreading both in and with Java in particular, this is a must. It's required reading if you're using threads heavilyDoug Lea, Concurrent Programming in JavaDesign Principles and Patterns (ReadingAddison Wesley, 1997) http://java.sun.com/docs/books/cp/
  • For a book on Java threading that is less technical but more readable than Lea's, seeScott Oaks and Henry Wong, Java Threads (Sebastopol, Calif.O'Reilly, 1997) http://www.oreilly.com/catalog/jthreads/
  • This book is good for the general subject of multithreading but doesn't have a Java slantBill Lewis and Daniel J. Berg, Threads PrimerA Guide to Multithreaded Programming (Englewood CliffsPrentice Hall/SunSoft Press, ISBN 0-13-443698-9) http://www.sun.com/books/books/Lewis/Lewis.html