问题描述
|
这与这个著名的SO问题相关但绝对不相同:
避免在Java中同步(this)?
通常,我有一个“可观察的主题”,它喜欢在修改后通知其观察者。通知基本上是在进行“外来方法”调用(因为它们在有效Java中被调用等),我可能会有类似这样的内容:
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() {
...
}
我是否应该避开synchronized(this)
,同时从getResult()
方法中删除ѭ2??
建议反对“ 1”字的人推荐以下内容:
private final Object lock = new Object(); // shiny lock
public void updateDate(params) {
synchronized( lock ) {
...
}
notifyObservers();
}
public Result getResult() {
synchronized( lock ) {
return Result;
}
}
作为一个额外的问题,它并不能保证它是自己的SO问题:如果建议使用后者,那么建议不使用synced(this)的人们会想到以下事实:Java中的方法可以声明为“ synchronized” \“?
解决方法
如果您担心公开锁,则不想使其成为API的一部分,或者您有更细粒度的锁策略,而一个锁还不够,那么您可以在使用私有锁时使用描述。
但是请注意,还有另一个更灵活的选择::6ѭ。您所提到的问题中未提及的固有锁的缺点之一是它们仅支持不间断的锁获取。另一方面,ѭ6提供了检查锁定状态,中断获取和超时获取的方法。
可中断获取在编写可取消任务时特别有用,因为它遵循阻止方法抛出InterruptedException的一般规定,以发出阻止操作中的线程中断的信号。来自中断的取消机制后面是java.util.concurrent中的执行程序。