首页 新闻 会员 周边

Java Thread 一些疑问,当run方法里面是i++的时候,运行是正常的,主线程未退出,但当替换成如下System.out.println,则主线程为什么会退出?

0
悬赏园豆:20 [已解决问题] 解决于 2023-01-13 14:21

为什么我把run()方法里面的i++换成System.out.println("This is running...");,flag也没加volatile关键字,程序运行之后,主线程退出?按道理flag没有加volatile,主线程是无法进行修改另一个线程的本地变量。

public class VolatileTest extends Thread {
    boolean flag = true;
    int i = 0;

    @Override
    public void run() {
        while (flag) {
            //i++;
            System.out.println("This is running...");
        }
    }

    public static void main(String[] args) throws Exception {
        VolatileTest vt = new VolatileTest();
        vt.start();
        Thread.sleep(1000);
        vt.flag = false;
    }
}
  • 符合预期,run方法内部 i++, 主线程等待
  • 不符合预期,run方法内部 System.out.println, 主线程退出
joseshiang的主页 joseshiang | 初学一级 | 园豆:184
提问于:2023-01-06 15:42
< >
分享
最佳答案
0

System.out.println 是个synchronized方法

收获园豆:20
让我发会呆 | 老鸟四级 |园豆:2929 | 2023-01-09 17:12

System.out.println确实是同步方法,但是不太明白是怎么影响的

joseshiang | 园豆:184 (初学一级) | 2023-01-10 10:20

@joseshiang: volatile关键字是解决可见性和有序性,你的flag字段,在run方法执行的时候,因为可见性问题对于当前线程一直都是false, 而synchronized方法可以让线程刷新主内存,涉及到JMM的知识了,我的大致理解是这样的

让我发会呆 | 园豆:2929 (老鸟四级) | 2023-01-10 10:35

@joseshiang: https://www.cnblogs.com/yxy-ngu/p/15686786.html 关于volatile关键字的一些理解,你可以参考下, 嘻嘻

让我发会呆 | 园豆:2929 (老鸟四级) | 2023-01-10 10:38

@让我发会呆: 我验证了一下,确实是synchronized影响的,感谢大佬

joseshiang | 园豆:184 (初学一级) | 2023-01-10 11:17
其他回答(2)
0

没太看懂,flag值为true当然退出

飞天蜗牛 | 园豆:209 (菜鸟二级) | 2023-01-06 17:47

之前问题描述的不太清晰,现在我补充了运行截图

支持(0) 反对(0) joseshiang | 园豆:184 (初学一级) | 2023-01-10 09:54
0

和Java的重排指令有关,你用 volatile 修饰你的 flag 字段就正常了,感兴趣可以打印一下指令看看

Epiphanyi | 园豆:202 (菜鸟二级) | 2023-01-07 19:18

刚了解下,多线程下重排指令确实有可能会出现问题,感谢!

支持(0) 反对(0) joseshiang | 园豆:184 (初学一级) | 2023-01-10 09:57
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册