【问题标题】:Is not volatile keyword required here in this multithreaded code? [duplicate]在这个多线程代码中这里不需要 volatile 关键字吗? [复制]
【发布时间】:2015-03-02 05:19:23
【问题描述】:

我在http://tutorials.jenkov.com/java-concurrency/thread-signaling.html看到了这个例子:

public class MySignal{

  protected boolean hasDataToProcess = false;

  public synchronized boolean hasDataToProcess(){
    return this.hasDataToProcess;
  }

  public synchronized void setHasDataToProcess(boolean hasData){
    this.hasDataToProcess = hasData;  
  }

}

我不明白为什么在声明布尔值“hasDataToProcess”时不使用 volatile 关键字。如果线程 A 将其设置为 true,它可能只会反映在其本地缓存中而不是主内存中,因此如果线程 B 从主内存或从其单独的本地缓存中读取,可能永远不会看到它设置为 true?

在本教程的前一章中,作者解释了声明变量 volatile 的重要性,但随后他提出了一个不符合早期指南的示例,因此我对 volatile 的用法有点困惑。

请帮助了解何时使用或不使用 volatile 以及这段代码是否需要它?如果是,为什么?如果没有,为什么不呢?

【问题讨论】:

  • 你在说什么“本地缓存”?

标签: java multithreading volatile


【解决方案1】:

没有。

hasDataToProcess 的所有访问都在同一锁上的块synchronized 内。 volatile 不是必需的。

【讨论】:

  • 使用同步如何解决问题?据我了解, volatile 确保所有读取和写入都发生在主内存中。因此,在上述情况下(不使用 volatile),如果线程 A 将其设置为“true”,则它可能仅发生在线程 A 的本地缓存中。现在,当线程 B 读取它时,它会从主内存中读取它,从而导致在阅读“假”时,这是出乎意料的。您能否在这些方面多解释一下。仅同步确保一次只有一个线程进入同步方法。对吗?
  • @abhishek08aug - 错误。 synchronized 使线程在进入块时适当地刷新其缓存。
  • 谢谢!热舔!这是怀疑的根本原因!
  • @abhishek08aug 这是一个常见的神话。 volatile 关键字与读取或写入是否发生在主内存中无关。现代硬件不能那样工作。 volatile 关键字确保读取和写入对其他线程立即可见。这与主存完全无关,在现代 CPU 上,完全在缓存中完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
相关资源
最近更新 更多