【问题标题】:Java method vs member synchronizationJava 方法与成员同步
【发布时间】:2021-05-27 22:40:21
【问题描述】:

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

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

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

class Thing {
   InnerThing innerThing;
   OtherInnerThing otherInnerThing;

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

【问题讨论】:

  • “只保护同时使用它的其他成员之间的并发访问”——这个。虽然同步不是原始的......

标签: java concurrency synchronized


【解决方案1】:

是这个原语只保护的合约吗 跨其他成员的并发访问 使用它,或跨任何同步的成员 此对象的任何底层成员。

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

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

这在Java Language Specification 中是隐含的;措辞谈到“同一台显示器”。

【讨论】:

  • 正确,但值得注意的是,没有“成员对象”之类的东西。只有两个不同的对象,一个被另一个的成员变量引用的事实是无关紧要的。可能这是唯一的引用,这使得对象在概念上包含在另一个中,但这是应用程序逻辑,而不是 Java 语言逻辑。此时 JVM 不检查是否有其他引用,因此行为与跨运行时共享的对象没有什么不同,因此在概念上不包含在另一个对象中。
  • 你是对的,当然。我的措辞很松散。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多