ReadWriteLock’s on Collections

Many people don’t realize that Collections.synchronized* causes an exclusive monitor lock to be held in every method called on the specified Collection object. For example:

final List list = Collections.synchronizedList(new ArrayList());

Thread th1 = new Thread(new Runnable() {
public void run() {
for(int i = 0; i < Integer.MAX_VALUE; i++) { list.add(Integer.valueOf(i)); } } }); Runnable reader = new Runnable() { public void run() { for(int i = 0; i < Integer.MAX_VALUE; i++) { list.get(i); } } }; Thread th2 = new Thread(reader); Thread th3 = new Thread(reader); Thread th4 = new Thread(reader); th1.start(); th2.start(); th3.start(); th4.start();[/sourcecode]I am well aware that the code for reading is very bad, but it serves the point. Four Threads, one writing to a synchronized Collection, the others reading from it. This as such is not a problem: writing to a Collection should only ever be done by one thread at a time, while no other threads are reading. However, any number of threads can read from the Collection at the same time. Collections.synchronized* acquires an exclusive lock for both read and write methods, so: only one thread will be allowed to access the Collection at a time.

The solution: Use a ReentrantReadWriteLock, which allows any number of Read locks at a time, but only one Write lock (and no Read locks while a Write lock is held).

There is an even more efficient way to make a Collection thread safe: use an inherently thread-safe collection. Just take a look in java.util.concurrent, and you’ll see that Java comes packed with plenty of them. You will need to decide which method is preferred for what you are doing. Take into account:

  • How many reads vs. how many writes
  • How large is the collection
  • How fast does the code need to execute
  • How often will the collection actually be accessed

3 Responses to “ReadWriteLock’s on Collections”

  1. rayfd Says:

    Got to this post of yours from your comment on my post πŸ™‚ Good article! BTW what do you use for displaying source code? That is excellent. Much better than my copy-paste-from-MS-Word method πŸ™‚

  2. SM Says:

    Don’t understand the point you are trying to illustrate. Running the above code is going to result in IndexOutOfBoundsException being thrown all over the place as readers race ahead of writer. Weren’t you trying to describe the latency problem of locks in this post?

  3. Jason Says:

    This is true, the code will leave you with the IndexOutOfBoundsException’s all over the place, the point of the post was not to demonstrate the importance of inter-thread-communication (which the above example badly neglects).

    My point was to demonstrate the fact that in the above example, only one thread will ever be able to access the List at a time, whether it is reading or writing. What is really wanted is a ReadWriteLock, so that any number of Threads may read at the same time, while only one Thread may access it if the Write lock is held.

    Like I said just below the code: I am well aware that the code for reading is very bad, but it serves the point.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: