The most obvious things for the lock in Jan's object to protect are the data for Jan, along with Jan's
"next" pointer. A better choice is to have that lock protect the data in Kim's object along with Jan's
"next" pointer. What that lock cannot protect is the pointer list, because the only way to find Jan
in the first place is to follow list. So even though you may hold Jan's lock, another thread will still
be able to come in and take Jan off the queue by changing list. This is why it's better to have
Jan's lock protect Kim's data. You need to hold Jan's lock anyway in order to access Kim, so why
complicate matters?
What if you have another thread which has a pointer (ptr) to Kim? You'd better not. Only the
thread that holds Jan's lock is allowed to access Kim's object, except for data that is constant or
data that might be out of date and you don't mind. Now if you remove Kim from the list, things
change. Jan's lock will no longer protect Kim (it will now protect Kari) and you will be able to do
anything you want with Kim's object because the thread that removes Kim from the list will be the
only thread that has access to Kim. If you then pass Kim to another thread, you will need to come
up with another method of protecting Kim.
The main point here is that when manipulating complex data structures you need to consider your
locking scheme carefully.
Double-Checked Locking
In a small number of very restricted cases, it is reasonable and legal to look at shared data values
without holding any locks. Obviously, anything that's a constant may be used without a lock. In
Java this includes objects that also contain shared variables and that may be moved onto or off of
shared lists. [This is a different situation than in C/C++, where you explicitly return unneeded
structures to the heap via free(). In Java, the garbage collector will take care of that.]
The other situation where you may look at unprotected shared data is when you don't mind if that
data is out of date. A monitor that runs a periodic display of the current value of some variable is
always going to lag behind the actual value of that variable. You could reasonably look at the
value in question without locking as long as that value is guaranteed to change atomically. So
values of type int, char, and float, along with pointers, are fine. Depending upon your
hardware, 64-bit values such as double and long may also be legal. Of course, you will not
know how much the value of that variable changes while you're displaying it. If it has a sudden
peak to 10 times its previous value, is that important? You're the programmer.
Search WWH :
Custom Search
Previous Page
Multithreaded Programming with JAVA - Topic Index
Next Page
Multithreaded Programming with JAVA - Bookmarks