我想知道这两个场景在多线程环境中是否相同。
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保证在调度线程之前至少会执行一个方法语句。
答案 0 :(得分:1)
它们在功能上是等价的(假设globalLock
是最终的实例变量)。
在你的第一个例子中,如果两个线程同时调用这两个方法,则只有一个线程能够获取锁定,第二个线程必须等到第一个释放锁定。
答案 1 :(得分:1)
目前尚不清楚全局锁是什么。如果是实例字段
private final Lock globalLock = new ReentrantLock();
public void addListener( Listener listener ) {
globalLock.lock();
...
那么答案是肯定的,这两种情况是等价的
答案 2 :(得分:0)
在多线程环境中,它们不完全等效。 在功能上它们与assylias建议的相同。
但他们在这两种方法之间存在很大差异。 最大的区别在于,在方案1中,您的锁是私有的。 因此,这是一个很好的做法,因为你确定没有其他人可以拥有你的锁。 虽然这种情况不是一种非常好的方法(在某些情况下除外),因为 任何其他用户都可以再锁定,因为现在您的锁是公开的。
因此在功能上相同,但通过设计它们是不同的。