gpt4 book ai didi

java - 为什么指令重新排序的 volatile 发生前顺序失败?

转载 作者:行者123 更新时间:2023-12-02 07:47:23 26 4
gpt4 key购买 nike

我有以下代码来测试 volatile bEndnCount 被定义为 volatile 的。

nCount = 0, bEnd = false

Writer 线程将设置

nCount = 100, bEnd = true

Reader 线程读取这些 viviable 并打印它们。基于 Java Happens-before 顺序,在我看来,当 bEnd = true 时,volatile 确保 nCount = 100。但有时程序会打印以下内容:

main thread done.
thread Reader running ...
thread Writer running ...
SharedData nCount = 0, bEnd = false
thread Writer bEnd = true
thread Reader nCount = 0, bEnd = true
thread Reader nCount = 100, bEnd = true
thread Reader nCount = 100, bEnd = true
thread Reader done.

Reader如何获得“nCount = 0,bEnd = true”???

以下代码在windows10、jdk1.8.0_131上运行

public class HappensBeforeWithVolatile {

public static void main(String[] args) {

Thread threadWriter = new Thread(new Writer());
Thread threadReader = new Thread(new Reader());
threadWriter.start();
threadReader.start();

System.out.println("main thread done.");
}
}

class Writer implements Runnable {

@Override
public void run() {
System.out.println("thread Writer running ...");
SharedData.nCount = 100;
// System.out.println("thread Writer nCount = 100");
SharedData.bEnd = true;
System.out.println("thread Writer bEnd = true");
}
}

class Reader implements Runnable {

@Override
public void run() {
System.out.println("thread Reader running ...");
System.out.println("thread Reader nCount = " + SharedData.nCount + ", bEnd = " + SharedData.bEnd);
System.out.println("thread Reader nCount = " + SharedData.nCount + ", bEnd = " + SharedData.bEnd);
if (SharedData.nCount == 0 && SharedData.bEnd) {
System.out.println("thread Reader CODE REORDER !!!");
}
System.out.println("thread Reader nCount = " + SharedData.nCount + ", bEnd = " + SharedData.bEnd);
System.out.println("thread Reader done.");
}
}

class SharedData {
volatile public static boolean bEnd = false;
volatile public static int nCount = 0;

static {
System.out.println("SharedData nCount = " + nCount + ", bEnd = " + bEnd);
}
}

最佳答案

当 bEnd = true 时, volatile 确保 nCount = 100

从技术上来说,是的。但读者并没有自动地阅读它们。因此它可能会打印 nCount = 0 和 bEnd = true

这是一个例子:

  1. 读取器读取nCount 0
  2. Wirter 写道 nCount = 100
  3. Wirter 写道 bEnd = true
  4. Writer 打印 thread Writer bEnd = true
  5. 读者读取bEnd true

关于java - 为什么指令重新排序的 volatile 发生前顺序失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51742302/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com