This is related, but definitely not identical, to this famous SO question:
Avoid synchronized(this) in Java?
Very often I've got an "observable subject" that likes to notify its observers when it is modified. The notification is basically making "alien method" calls (as they're called in Effective Java etc.) I may have something like this:
public void updateData(params) {
synchronized (this) {
// do some computation here
}
notifyObservers(); // Never, EVER, call an alien method with a lock held (see Effective Java)
}
public synchronized Result getResult() {
...
}
Should I be avoiding the synchronized(this)
and hence also remove the synchronized
from the getResult()
method?
Is this the following that people advising against synchronized(this)
are recommending:
private final Object lock = new Object(); // shiny lock
public void updateDate(params) {
synchronized( lock ) {
...
}
notifyObservers();
}
public Result getResult() {
synchronized( lock ) {
return Result;
}
}
As a bonus question that doesn't warrant it's own SO question: if the latter is recommended, what do people who advise against using synchronized(this) think about the fact开发者_JS百科 that methods in Java can be declared as "synchronized"?
If you are concerned about exposing your lock, you don't want to make it a part of your API or you have a finer-grained locking policy and one lock isn't enough, you could use use a private lock as you described.
Note however that there is another, much more flexible alternative: ReentrantLock
. One of the disadvantages of intrinsic locks not mentioned in the question which you referred to is that they only support uninterruptible lock acquisition. On the other hand, ReentrantLock
provides methods for checking lock status, interruptible acquisition and acquisition with a timeout.
Interruptible acquisition is particularly useful when writing cancelable tasks since it follows the general prescription for blocking methods to throw InterruptedException to signal thread interruption in a blocking operation. The cancelation mechanism based on interruption is followed by Executors from java.util.concurrent.
精彩评论