img
. . .
would have been a mistake and we would have been using two different locks to protect the same
static variable. Don't do that.
Example 6-9 You May Use the Class Itself to Protect Static Data
public class Foo {
static int count = 0;
public void inc(int i) {
synchronized (Foo.class) {
count = count + i;
}
}
// cf: getClass()
}
Now let's look at that shared list example implemented in Java (Code Example 6-10). No surprise,
the code looks virtually identical to the POSIX code. (The two methods are part of a class
Workpile, which we'll see a bit later.)
Example 6-10 Protecting a Shared List with a Mutex (Java)
Thread 1
Thread 2
synchronized void add(Request r)
{
r.next = requests;
synchronized Request remove() {
requests = r;
}
...sleeping...
r = requests;
requests = requests.next;
return(r);
}
For the (rare) situation when you do not want to go to sleep, a trylock function is included in
POSIX and Win32. In POSIX, pthread_mutex_trylock() returns 0 if you get the lock and
EBUSY if you don't. (Win32 functions have timeouts for the same purpose.) If you get EBUSY,
you'll have to figure out something else to do, as entering the critical section anyway would be
highly antisocial. This function is used very rarely, so if you think you want it, look very carefully
at what you're doing![6] [See Making malloc() More Concurrent.] There is no such functionality in
Java. This is not a particular problem, as Java does not address itself to the kinds of low-level,
realtime problems that trylock is useful for.
[6]
We apologize if these warnings seem a bit much. We realize that you understand the issues
involved. We just want to make it clear for that other programmer.
It is important to realize that although locks are used to protect data, what they really do is to
prevent more than one thread from running the section of code they bracket (assuming that the
same mutex is being used). There's nothing that forces another programmer (who writes another
function that uses the same data) to lock his code--nothing but good programming practice.
Moreover, there is no automatic connection between the object's lock and the object's instance
variables. Although it seems obvious that one would use the lock from object1 to protect the
instance variables of object1, it isn't a requirement and there are situations where you want to
use the lock from object2 to protect the data of object1! Nonetheless, it is a nice feature of
object-oriented programming for the lock to be encapsulated with the data, making it that much
less likely for you to make a mistake.
Search WWH :
Custom Search
Previous Page
Multithreaded Programming with JAVA - Topic Index
Next Page
Multithreaded Programming with JAVA - Bookmarks
Home