IDEA 或者 JDK 会自动优化由于变量共享产生的非线程安全问题吗?

2022-08-25 16:52:19 +08:00
 qiaofanxing

刚接触多线程编程,想复现一下书上写的“实例变量共享导致的非线程安全问题”,但是发现怎么尝试都无法得出错误的结果,运行了几十次都是 5000 ,是因为在某一项生成过程中被自动优化了吗?附上代码:

public class MyThread extends Thread{
    public int getCount() {
        return count;
    }

    private int count = 0;

    @Override
    public void run() {
        super.run();
        for(int i = 0 ; i < 1000 ; i++)
        {
            count++;
        }
    }
}
import static java.lang.Thread.sleep;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        MyThread mythread = new MyThread();

        Thread a = new Thread(mythread,"A");
        Thread b = new Thread(mythread,"B");
        Thread c = new Thread(mythread,"C");
        Thread d = new Thread(mythread,"D");
        Thread e = new Thread(mythread,"E");
        a.start();
        b.start();
        c.start();
        d.start();
        e.start();
        sleep(1000);
        System.out.println(mythread.getCount());
    }
}

1664 次点击
所在节点    Java
16 条回复
xgfan
2022-08-25 16:54:39 +08:00
才循环 1000 次,够干啥,B 还没启动,A 可能就结束了。
selca
2022-08-25 16:57:12 +08:00
ide 不会去优化这种
qiaofanxing
2022-08-25 16:59:15 +08:00
@xgfan 感谢!我把循环次数加到 1000000 次了,终于复现问题了...因为书上示例写的是 1000 次就极大概率出现问题,我就没往这个方面多想了。
gengchun
2022-08-25 16:59:17 +08:00
用 ab 压吧。
oldshensheep
2022-08-25 17:04:17 +08:00
也可以 sleep 一下。也许是现在的电脑太快了吧……🤣
MarkP
2022-08-25 17:06:36 +08:00
电脑性能太好了。

不妨线程搞多些,多跑几次。
justanetizen
2022-08-25 17:07:33 +08:00
Chinsung
2022-08-25 17:43:08 +08:00
大概率是执行太快了,说说遇到过的另一个情况,之前也是验证并发问题,在行里,然后无论怎么压在开发机上都无法复现
后面发现:行里的开发机是单核的
chengyiqun
2022-08-26 10:55:07 +08:00
@qiaofanxing #3 因为书上是以前低性能电脑测出来的, 现在的电脑性能比以前强多了.
chengyiqun
2022-08-26 11:04:02 +08:00
不过我还是姑且问下, 你电脑多少核心吧.
我是笔记本 i7-8750H, 6 核 12 线程, 1000 循环有时可复现, 有时候不行.
chengyiqun
2022-08-26 11:10:52 +08:00
chengyiqun
2022-08-26 11:21:18 +08:00
main 方法可以这样写, 不要 sleep 啦
public static void main(String[] args) throws InterruptedException {
MyThread mythread = new MyThread();
List<Thread> tList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(mythread, String.valueOf(i + 1));
tList.add(thread);
thread.start();
}
for (Thread thread : tList) {
thread.join();
}
System.out.println(mythread.getCount());
}
qiaofanxing
2022-08-26 11:48:31 +08:00
@chengyiqun 我也是 i7-8750H ,1000 循环稳定复现不出来,所以我才懵了
qiaofanxing
2022-08-26 11:53:57 +08:00
@chengyiqun 我在后面做其他实验的时候发现,单次循环超过 3 万 1 多次才会出现上下文切换,3 万以内的简单循环一个时间片就跑完了,现在的电脑性能真是强大
xuanbg
2022-08-26 12:13:07 +08:00
OP 你大可不必担心,无论是 IDE 还是 JVM ,都是不会优化这个的。因为这个自动优化不了。
cco
2022-08-31 11:37:50 +08:00
你用奔四处理器跑,或许能成功,现在电脑 CPU 这么强劲,你搞个 1000 玩呢。

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

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

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

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

© 2021 V2EX