synchronized(this)和观察者通知

时间:2011-04-13 12:32:17

标签: java synchronization locking observer-pattern

这与这个着名的SO问题有关,但绝对不相同:

Avoid synchronized(this) in Java?

我常常有一个“可观察的主题”,它喜欢在修改时通知观察者。通知基本上是“外来方法”调用(因为它们在 Effective 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),因此也会从synchronized方法中移除getResult()吗?

以下是针对synchronized(this)提出建议的人建议:

private final Object lock = new Object(); // shiny lock

public void updateDate(params) {
    synchronized( lock ) {
       ...
    }
    notifyObservers();
}

public Result getResult() {
    synchronized( lock ) {
        return Result;
    }
}

作为一个奖励问题,不能保证它自己的SO问题:如果建议使用后者,建议不要使用 synchronized(this)的人会考虑Java中的方法可以被宣布为“同步”?

1 个答案:

答案 0 :(得分:1)

如果你担心暴露你的锁,你不想让它成为你的API的一部分,或者你有一个更细粒度的锁定策略和一个锁是不够的,你可以使用私人锁作为你描述过。

但请注意,还有另一种更灵活的选择:ReentrantLock。您提到的问题中未提及的内在锁的缺点之一是它们仅支持不间断锁获取。另一方面,ReentrantLock提供了检查锁定状态,可中断采集和超时采集的方法。

在编写可取消任务时,可中断采集特别有用,因为它遵循阻塞方法的general prescription,以便在阻塞操作中发出InterruptedException来表示线程中断。基于中断的取消机制之后是来自Executorsjava.util.concurrent