刚接触多线程编程,想复现一下书上写的“实例变量共享导致的非线程安全问题”,但是发现怎么尝试都无法得出错误的结果,运行了几十次都是 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()); } }
![]() | 1 6IbA2bj5ip3tK49j 2022-08-25 16:54:39 +08:00 ![]() 才循环 1000 次,够干啥,B 还没启动,A 可能就结束了。 |
![]() | 2 selca 2022-08-25 16:57:12 +08:00 ide 不会去优化这种 |
![]() | 3 EeveeRibbon OP @xgfan 感谢!我把循环次数加到 1000000 次了,终于复现问题了...因为书上示例写的是 1000 次就极大概率出现问题,我就没往这个方面多想了。 |
4 gengchun 2022-08-25 16:59:17 +08:00 用 ab 压吧。 |
![]() | 5 oldshensheep 2022-08-25 17:04:17 +08:00 也可以 sleep 一下。也许是现在的电脑太快了吧…… |
![]() | 6 MarkP 2022-08-25 17:06:36 +08:00 电脑性能太好了。 不妨线程搞多些,多跑几次。 |
![]() | 7 justanetizen 2022-08-25 17:07:33 +08:00 |
8 Chinsung 2022-08-25 17:43:08 +08:00 大概率是执行太快了,说说遇到过的另一个情况,之前也是验证并发问题,在行里,然后无论怎么压在开发机上都无法复现 后面发现:行里的开发机是单核的 |
![]() | 9 C02TobNClov1Dz56 2022-08-26 10:55:07 +08:00 @qiaofanxing #3 因为书上是以前低性能电脑测出来的, 现在的电脑性能比以前强多了. |
![]() | 10 C02TobNClov1Dz56 2022-08-26 11:04:02 +08:00 不过我还是姑且问下, 你电脑多少核心吧. 我是笔记本 i7-8750H, 6 核 12 线程, 1000 循环有时可复现, 有时候不行. |
![]() | 11 C02TobNClov1Dz56 2022-08-26 11:10:52 +08:00 |
![]() | 12 C02TobNClov1Dz56 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()); } |
![]() | 13 EeveeRibbon OP @chengyiqun 我也是 i7-8750H ,1000 循环稳定复现不出来,所以我才懵了 |
![]() | 14 EeveeRibbon OP @chengyiqun 我在后面做其他实验的时候发现,单次循环超过 3 万 1 多次才会出现上下文切换,3 万以内的简单循环一个时间片就跑完了,现在的电脑性能真是强大 |
![]() | 15 xuanbg 2022-08-26 12:13:07 +08:00 OP 你大可不必担心,无论是 IDE 还是 JVM ,都是不会优化这个的。因为这个自动优化不了。 |
![]() | 16 cco 2022-08-31 11:37:50 +08:00 你用奔四处理器跑,或许能成功,现在电脑 CPU 这么强劲,你搞个 1000 玩呢。 |