首页 > 解决方案 > 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();
      }
   }
}

标签: javaconcurrencysynchronized

解决方案


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

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

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

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


推荐阅读