研究 volatile 时遇到一个困惑的问题

2019-06-24 16:25:54 +08:00
 ahjiangwu

volatile 实现线程之间的可见性的示例如下:

import java.util.concurrent.TimeUnit;

public class volatileTest {
    public static void main(String[] args) {

        Data data = new Data();

        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
                data.addPlusPlus();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "T1").start();

        while (data.number == 0) {
            //System.out.println(data.number);  注意这一行注释了
        }
        System.out.println("number > 0");

        while (Thread.activeCount() > 2) {
            Thread.yield();
        }
    }
}

class Data {
    //volatile int number = 0;
    int number = 0;

    public void addPlusPlus() {
        this.number ++;
    }
}

当把

int number = 0; 

改为

volatile int number = 0;

时确实实现了主线程打印结果

然而

number 没有加 volatile 之前,while 循环中有注释的那一行时,主线程依然可以打印结果

这是为什么???

2408 次点击
所在节点    Java
5 条回复
NullErro
2019-06-24 17:40:21 +08:00
你 start 之后暂停一段时间再看看是不是你这个结论呢,start()之后并不一定就立即启动 T1 这个线程了
momocraft
2019-06-24 17:44:42 +08:00
保证可见的反面是 “不保证可见” ,不是 “保证不可见”
superalsrk
2019-06-24 17:53:51 +08:00
2L 说的对
sagaxu
2019-06-24 17:54:47 +08:00
因为 System.out.println 里面有同步机制,基于 happens-before 的可传递性原则,你的代码执行之间也同步了
zjp
2019-06-25 00:47:56 +08:00
4L 说的对
https://www.v2ex.com/t/539969
写出正确的并发测试不容易,可能还需要注意 JIT

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/576970

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX