假设我有这个java代码:
synchronized(someObject)
{
someObject = new SomeObject();
someObject.doSomething();
}
在调用doSomething()时,SomeObject的实例是否仍然被锁定?
答案 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);
}
首先评估表达式,执行同步语句。
如果表达式的评估由于某种原因突然完成,那么同步语句会因同样的原因而突然完成。
否则,如果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