内在和显式全局锁定的Java等价

时间:2013-08-01 11:47:06

标签: java multithreading concurrency

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

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()方法,则线程B仍有可能获取尽管线程A在线程B调用removeListener()之前调用了addListener(),但在线程A之前锁定。这个假设是正确的还是Java保证在调度线程之前至少会执行一个方法语句。

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

private final Lock globalLock = new ReentrantLock();

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

那么答案是肯定的,这两种情况是等价的

答案 2 :(得分:0)

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

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

因此在功能上相同,但通过设计它们是不同的。