Lock on to an alternate synchronization mechanism
Learn how to implement a reader/writer lock for flexible protection
By Tarak Modi, JavaWorld.com, 07/14/00
Software professionals have been debating multithreaded programming for quite some time now. The notion of threading is so
ingrained within the Java platform that developers can rarely create even simple programs without inadvertently using threads.
Although the built-in threading support within the Java platform has allowed developers to create powerful programs, it has
also left its share of scarred developers. The most common hazards lie in event-handling and the access of AWT/JFC Swing components.
Rudimentary as it is, Java's built-in thread support is powerful enough to help build the most complex synchronization mechanisms
required for commercial applications. The aim of this article is to illustrate that power by creating a reader/writer lock.
The reader/writer lock implementation discussed here includes lock upgrade and downgrade capabilities. I'll also examine enhancements
such as
lock-leasing, various performance improvement tips, and ways of dealing with issues such as
priority inversion.
The reader/writer lock
I would like to clear up the fair amount of misconception that remains about the reader/writer lock. The name implies the
presence of two distinct locks -- one for reading and one for writing. However, that is not the case. A reader/writer lock
is a single lock. Think of it as a lock with two levels, much like a building with two floors or a game with two levels -- beginner and
advanced.
A reader/writer lock can be acquired simultaneously by multiple threads as long as the threads only read from the shared resource
that the lock is protecting. If the thread wants to write or modify the shared resource, only one thread at a time can acquire
the lock.
That lock is useful if the read operation is lengthy, and no reason presents itself in preventing other threads from reading
the shared resource at the same time -- reading a file, reading the value of a static class variable, or reading a row from
a table in a database, as examples. However, to ensure data integrity, only one thread can modify the shared resource. While
it is making changes, no other threads are allowed access to the resource, even to read it. Thus, no other thread sees any
intermediate changes or values of the shared resource.
Consider a list of all the names of people who have ever lived on the face of the earth as an example. The list is singly-linked,
meaning traversal is possible in only one direction. Since it is a list, no random access is allowed. The list of names is
huge -- several billion people long, at least. Searching for a particular individual in such a list is time-consuming in itself.
Now imagine a million clients accessing the list continuously, each one either looking for an individual, or inserting a newly
born person in the list, or both. The simplest multithreaded program would synchronize on the list during the search and insert
operations. But that means that we have serialized all access to the list, thereby foregoing almost all benefits bestowed
upon us by Java's multithreaded capability.
Resources
- Concurrent Programming in Java, Second EditionDesign Principles and Patterns (The Java Series), Douglas Lea (Addison-Wesley, 1999)
http://www.amazon.com/exec/obidos/ASIN/0201310090/qid=959375977/sr=1-1/103-0642573-2563859
- Java Threads, Scott Oaks, Henry Wong, and Mike Loukides (O'Reilly & Associates, 1999)
http://www.amazon.com/exec/obidos/ASIN/1565924185/o/qid=959376189/sr=2-1/103-0642573-2563859
- A book that all serious software professionals should read (we have used at least one design pattern from the book; figuring
out which one would be a good exercise)Design PatternsElements of Reusable Object-Oriented Software, Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, and Grady Booch (Addison-Wesley, 1995)
http://www.amazon.com/exec/obidos/ASIN/0201633612/qid=959376526/sr=1-1/103-0642573-2563859
- We used a pattern from that source's section on double-checked locking at multiple places within the code. Its usage is a
must for multithreaded programmingPattern Languages of Program Design 3 (Software Patterns Series), Robert C. Martin, Dirk Riehle, Frank Buschmann, and John Vlissides (Addison-Wesley, 1997)
http://www.amazon.com/exec/obidos/ts/book-contents/0201310112/ref=pm_dp_ln_b_2/103-0642573-2563859
- For a discussion on replacing a better-performing implementation by using a for loop to iterate through the listJava 2 Performance and Idiom Guide, Craig Larman and Rhett Guthrie (Prentice Hall, 1999)
http://www.amazon.com/exec/obidos/ASIN/0130142603/o/qid=959375422/sr=8-1/ref=aps_sr_b_1_1/103-0642573-2563859
- "Programming Java Threads in the Real World, Part 1," Allen Holub (JavaWorld, September 1998)
http://www.javaworld.com/javaworld/jw-09-1998/jw-09-threads.html
- "Programming Java Threads in the Real World, Part 2," Allen Holub (JavaWorld, October 1998)
http://www.javaworld.com/javaworld/jw-10-1998/jw-10-toolbox.html
- "Programming Java Threads in the Real World, Part 3," Allen Holub (JavaWorld, November 1998)
http://www.javaworld.com/javaworld/jw-11-1998/jw-11-toolbox.html
- "Programming Java Threads in the Real World, Part 4," Allen Holub (JavaWorld, December 1998)
http://www.javaworld.com/javaworld/jw-12-1998/jw-12-toolbox.html
- "Programming Java Threads in the Real World, Part 5," Allen Holub (JavaWorld, February 1999)
http://www.javaworld.com/javaworld/jw-02-1999/jw-02-toolbox.html
- "Programming Java Threads in the Real World, Part 6," Allen Holub (JavaWorld, March 1999)
http://www.javaworld.com/javaworld/jw-03-1999/jw-03-toolbox.html
- "Programming Java Threads in the Real World, Part 7," Allen Holub (JavaWorld, April 1999)
http://www.javaworld.com/javaworld/jw-04-1999/jw-04-toolbox.html
- "Programming Java Threads in the Real World, Part 8," Allen Holub (JavaWorld, May 1999)
http://www.javaworld.com/javaworld/jw-05-1999/jw-05-toolbox.html
- "Programming Java Threads in the Real World, Part 9," Allen Holub (JavaWorld, June 1999)
http://www.javaworld.com/javaworld/jw-06-1999/jw-06-toolbox.html