Java方法与成员同步

我知道 java 的同步原语,当应用于方法时,在语义上等同于在方法执行期间锁定对象本身。

但是,我不清楚同时访问对象的特定成员的这个原语的契约 wrt 方法。这个原语是否只保护其他也使用它的成员之间的并发访问,或者在这个对象的任何底层成员上同步的任何成员之间的并发访问?

例如,如果同时调用下面示例中的 foo() 和 bar(),是否会导致数据竞争innerThing

class Thing {
   InnerThing innerThing;
   OtherInnerThing otherInnerThing;

   public synchronized void foo() {
      innerThing.mutate();
    }
  
  public void bar() {
      synchronized(innerThing) {
            innerThing.mutate();
      }
   }
}

回答

该原语仅保护其他也使用它的成员之间的并发访问,或在此对象的任何底层成员上同步的任何成员之间的并发访问。

前者。所有线程必须在同一个对象上同步。

如果线程 1 在实例上同步,并且线程 2 尝试在该实例的某个成员对象上同步,则线程 2 将不会被阻塞。

这在Java 语言规范中是隐含的;措辞谈到“同一台显示器”。

  • Correct, but it’s worth noting that there is no such thing as a “member object”. There are just two distinct objects and the fact that one is referenced by a member variable of the other, is irrelevant. It might be that this is the only reference, which makes the object conceptually being contained in the other, but that’s application logic, not Java language logic. The JVM doesn’t check whether there are other references at this point, so the behavior is not different to an object shared across the runtime thus not conceptually contained in another.

以上是Java方法与成员同步的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>