V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
qiaofanxing
V2EX  ›  Java

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

  •  
  •   qiaofanxing · 2022-08-25 16:52:19 +08:00 · 1622 次点击
    这是一个创建于 581 天前的主题,其中的信息可能已经有所发展或是发生改变。

    刚接触多线程编程,想复现一下书上写的“实例变量共享导致的非线程安全问题”,但是发现怎么尝试都无法得出错误的结果,运行了几十次都是 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());
        }
    }
    
    
    16 条回复    2022-08-31 11:37:50 +08:00
    xgfan
        1
    xgfan  
       2022-08-25 16:54:39 +08:00   ❤️ 1
    才循环 1000 次,够干啥,B 还没启动,A 可能就结束了。
    selca
        2
    selca  
       2022-08-25 16:57:12 +08:00
    ide 不会去优化这种
    qiaofanxing
        3
    qiaofanxing  
    OP
       2022-08-25 16:59:15 +08:00
    @xgfan 感谢!我把循环次数加到 1000000 次了,终于复现问题了...因为书上示例写的是 1000 次就极大概率出现问题,我就没往这个方面多想了。
    gengchun
        4
    gengchun  
       2022-08-25 16:59:17 +08:00
    用 ab 压吧。
    oldshensheep
        5
    oldshensheep  
       2022-08-25 17:04:17 +08:00
    也可以 sleep 一下。也许是现在的电脑太快了吧……🤣
    MarkP
        6
    MarkP  
       2022-08-25 17:06:36 +08:00
    电脑性能太好了。

    不妨线程搞多些,多跑几次。
    Chinsung
        8
    Chinsung  
       2022-08-25 17:43:08 +08:00
    大概率是执行太快了,说说遇到过的另一个情况,之前也是验证并发问题,在行里,然后无论怎么压在开发机上都无法复现
    后面发现:行里的开发机是单核的
    chengyiqun
        9
    chengyiqun  
       2022-08-26 10:55:07 +08:00
    @qiaofanxing #3 因为书上是以前低性能电脑测出来的, 现在的电脑性能比以前强多了.
    chengyiqun
        10
    chengyiqun  
       2022-08-26 11:04:02 +08:00
    不过我还是姑且问下, 你电脑多少核心吧.
    我是笔记本 i7-8750H, 6 核 12 线程, 1000 循环有时可复现, 有时候不行.
    chengyiqun
        11
    chengyiqun  
       2022-08-26 11:10:52 +08:00
    chengyiqun
        12
    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
        13
    qiaofanxing  
    OP
       2022-08-26 11:48:31 +08:00 via Android
    @chengyiqun 我也是 i7-8750H ,1000 循环稳定复现不出来,所以我才懵了
    qiaofanxing
        14
    qiaofanxing  
    OP
       2022-08-26 11:53:57 +08:00 via Android
    @chengyiqun 我在后面做其他实验的时候发现,单次循环超过 3 万 1 多次才会出现上下文切换,3 万以内的简单循环一个时间片就跑完了,现在的电脑性能真是强大
    xuanbg
        15
    xuanbg  
       2022-08-26 12:13:07 +08:00
    OP 你大可不必担心,无论是 IDE 还是 JVM ,都是不会优化这个的。因为这个自动优化不了。
    cco
        16
    cco  
       2022-08-31 11:37:50 +08:00
    你用奔四处理器跑,或许能成功,现在电脑 CPU 这么强劲,你搞个 1000 玩呢。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5425 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 474ms · UTC 08:46 · PVG 16:46 · LAX 01:46 · JFK 04:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.