Java 方法 vs 成员同步

Java method vs member synchronization

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

但是,我不清楚这个原语的契约w.r.t。同时访问对象的特定成员的方法。该原语是否仅保护同时使用它的其他成员之间的并发访问,或在该对象的 any 基础成员上同步的任何成员之间的并发访问?

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

class Thing {
   InnerThing innerThing;
   OtherInnerThing otherInnerThing;

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

Is the contract that this primitive only protects concurrent access across other members that also use it, or across any member that synchronizes on any underlying member of this object.

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

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

这隐含在Java Language Specification;措辞谈到 'the same monitor'.