我想要一个同步块,其中要同步的对象是从方法调用中返回的:
...
synchronized( someGetMethod() ) {
// synchronized block
}
...
是否假设“ someGetMethod”是同步的还是仅“ //同步块”部分?
提前谢谢
编辑: 我有一个集合(要锁定的对象映射)。 “ someGetMethod”检查对象是否存在于地图上,如果不存在,它将添加该对象并返回该对象以将其锁定。 从下面的答案中,我了解到“ someGetMethod”可以返回Map上已经存在的值,但是在进入同步块之前,请切换到另一个线程,这可能会删除上述值。结果,另一个线程可以通过“ someGetMethod”执行相同的检查,现在得到不同的结果。。所以看来我应该从同步块中进行删除,还有更好的选择吗?
Edit2: 谢谢大家的帮助。 我发现了类似的问题-Java synchronized block using method call to get synch object
答案 0 :(得分:4)
此:
synchronized( someGetMethod() ) {
// synchronized block
}
与
相同Object obj = someGetMethod();
synchronized( obj ) {
// synchronized block
}
因此,不会以同步方式调用someGetMethod()
。
如果要使其同步,则必须声明方法已同步,或显式同步,例如:
synchronized (this) {
synchronized( someGetMethod() ) {
// synchronized block
}
}
答案 1 :(得分:3)
someGetMethod()
是一个表达式,它在与与表达式结果关联的监视器被线程锁定之前被评估。
14.19. The synchronized Statement
首先通过计算表达式来执行同步语句。然后:
如果由于某种原因对表达式的求值突然完成,则由于相同的原因,同步语句也会突然完成。
否则,如果Expression的值为null,则将引发NullPointerException。
否则,将Expression的非null值设为V。执行线程锁定与V相关联的监视器。然后执行Block ,然后可以选择:
如果Block的执行正常完成,则监视器将解锁,并且synced语句也会正常完成。
如果由于某种原因突然终止了Block的执行,则监视器将被解锁,并且由于相同的原因,synchronized语句也会突然完成。
您无法输入同步块,计算表达式,然后查看与结果关联的监视器。 如何进入块时首先不评估其表达?您是用来同步someGetMethod()
本身的什么监视器?