当一个对象被锁定,并且该对象被替换时,是否保持了锁?

时间:2011-09-30 19:04:40

标签: java multithreading

假设我有这个java代码:

synchronized(someObject)
{
    someObject = new SomeObject();
    someObject.doSomething();
}

在调用doSomething()时,SomeObject的实例是否仍然被锁定?

4 个答案:

答案 0 :(得分:5)

在同步块结束之前,线程仍将拥有原始someObject的监视器。如果你想象有两种方法,Monitor.enter(Object)Monitor.exit(Object),那么synchronized块的行为类似于:

SomeObject tmp = someObject;
Monitor.enter(tmp);
try
{
    someObject = new SomeObject();
    someObject.doSomething();
}
finally
{
    Monitor.exit(tmp);
}

来自section 14.19 of the JLS

  

首先评估表达式,执行同步语句。

     

如果表达式的评估由于某种原因突然完成,那么同步语句会因同样的原因而突然完成。

     

否则,如果Expression的值为null,则抛出NullPointerException。

     

否则,让Expression的非null值为V.执行线程锁定与V关联的锁。然后执行Block。如果块的执行正常完成,则解锁并且synchronized语句正常完成。如果Block的执行因任何原因突然完成,则锁定被解锁,然后同步语句突然完成,原因相同。

请注意评估仅发生一次。

答案 1 :(得分:3)

锁定适用于对象,而不是变量。在someObject = new SomeObject();变量someObject引用新对象后,锁仍然在旧对象上。

再见,再见非常危险。

答案 2 :(得分:1)

我认为以前 someObject 的实例已被锁定,而您的实例未被锁定。

答案 3 :(得分:0)

了解同步方法与同步语句之间的区别非常重要。

请看一下这个很好地解释它的页面:http://download.oracle.com/javase/tutorial/essential/concurrency/locksync.html