|
|
The synchronized keyword in JavaDeclaring a method as synchronizedTo the programmer, declaring a method as synchronized is essentially the same as wrapping the method body in a synchronized (this) block. So the above Counter class could be written:
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
If we declare a static method as synchronized, then the lock is obtained on the corresponding Class object. Generally, which alternative used in cases such as this is a matter of style, although at the bytecode level there is actually a very slight difference1. However, there are some potential problems with declaring methods as synchronized:
Bloch and Gafter (2005) provide a fun example of the first problem, which I have adapted here. The Processor class below is intended to process in a separate thread jobs added via its addJob() method. The requestStopAndWaitToFinish() method is designed to tell the thread to stop running and prevent further jobs from being added. Both methods are synchronized, so that in theory a call to addJob() can't be run while the stop request method is running and waiting for the thread to finish:
public class Processor extends Thread {
private volatile boolean stopRequested;
public synchronized void requestStopAndWaitToFinish() {
stopRequested = true;
join();
}
public synchronized void addJob(Object job) {
if (!stopRequested) {
// ... interesting code
}
}
public void run() {
while (!stopRequested) {
// .. process jobs using more interesting code
}
}
}
What's not obviously wrong with this code at first sight is that the call to join() inside requestStopAndWaitToFinish() actually gives up the lock– via a call to Object.wait()– while waiting for the thread to finish, so that another thread can step in and run addJob()! The moral of the story is that you should always be very sure that nothing else is going to interfere with the lock acquired by a synchronized method, or else declare a separate, private Object to synchronize on. (But conversely, if you are sure that nothing else will interfere, it may not desirable to create lots of other spurious objects just for the purpose of synchronization.) On the next page, we look at the volatile keyword in Java, which is to some extent a "lighter" version of synchronization. Notes: Did this article answer your question? If not, visit the new
Javamex discussion forums to ask your question.
Copyright © Javamex UK 2009. All rights reserved. |