从方法返回的同步代码中的对象

时间:2019-10-06 10:01:47

标签: java synchronized synchronized-block

我想要一个同步块,其中要同步的对象是从方法调用中返回的:

...
synchronized( someGetMethod() ) {
// synchronized block
}
...

是否假设“ someGetMethod”是同步的还是仅“ //同步块”部分?

提前谢谢

编辑: 我有一个集合(要锁定的对象映射)。 “ someGetMethod”检查对象是否存在于地图上,如果不存在,它将添加该对象并返回该对象以将其锁定。 从下面的答案中,我了解到“ someGetMethod”可以返回Map上已经存在的值,但是在进入同步块之前,请切换到另一个线程,这可能会删除上述值。结果,另一个线程可以通过“ someGetMethod”执行相同的检查,现在得到不同的结果。。所以看来我应该从同步块中进行删除,还有更好的选择吗?

Edit2: 谢谢大家的帮助。 我发现了类似的问题-Java synchronized block using method call to get synch object

2 个答案:

答案 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()本身的什么监视器