0

我想知道这两个场景在多线程环境中是否等效。

private final Lock globalLock = new ReentrantLock();

方案 1

public void addListener( Listener listener ) {
    globalLock.lock();
    try{
    //blah blah
    }finally {
        globalLock.unlock();
    }
}

public void removeListener( Listener listener ) {
    globalLock.lock();
    try{
    //blah blah
    }finally {
        globalLock.unlock();
    }
}

方案 2

public synchronized addListener( Listener listener ) {
}

public synchronized removeListener( Listener listener ) {
}   

我认为第一种情况在多线程环境中存在竞争条件,因为如果线程 A在线程 B 调用 removeListener()之前调用 addListener() 方法,即使线程 A 调用 addListener ,线程 B 仍然有可能在线程 A 之前获取锁() 在线程 B 调用 removeListener() 之前。这个假设是正确的还是Java保证在线程被调度出来之前至少会执行该方法的一个语句。

4

3 回答 3

1

它们在功能上是等效的(假设globalLock是最终实例变量)。

在您的第一个示例中,如果两个线程同时调用这两个方法,则只有一个线程能够获取锁,而第二个线程必须等待第一个线程释放锁。

于 2013-08-01T11:50:19.887 回答
1

目前尚不清楚什么是全局锁。如果是实例字段

private final Lock globalLock = new ReentrantLock();

public void addListener( Listener listener ) {
    globalLock.lock();
    ...

那么答案是肯定的,这两种场景是等价的

于 2013-08-01T11:51:21.140 回答
0

它们在多线程环境中并不完全等效。是的,它们在功能上与 assylias 建议的相同。

但这两种方法之间存在很大差异。最大的区别在于,在场景 1 中,您的锁是私有的。因此这是一个很好的做法,因为您确定没有其他人可以拥有您的锁。虽然该场景不是一个很好的方法(在某些情况下除外),因为任何其他用户都可以再持有锁,因为现在您的锁是 public

所以在功能上是等效的,但在设计上它们是不同的。

于 2013-08-02T10:29:21.537 回答