Java 并发之《深入理解 JVM》关于 volatile 累加示例的思考

在周志明老师的 《深入理解 JVM》一书中关于 volatile 关键字线程安全性有一个示例代码(代码有些许改动,语义一样):

java 复制代码
public class MyTest3 {

    private static volatile int race = 0;

    private static void increase() {
        race++;
    }

    public static void main(String[] args) {
        IntStream.range(0, 20).forEach((item) -> {
            new Thread(() -> IntStream.range(0, 10000).forEach(i -> increase())).start();
        });
        while (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println(race);
    }
}

老师的目的是为了说明在多线程环境下 volatile 关键字只能保证可见性而不是线程安全的。但是当在我的 IDEA 下运行时,发现程序是没有输出结果且始终是终止不了的,有点纳闷,稍微一分析肯定是在 yield 这个地方有问题。所以尝试把当前 active 的线程打印出来:

java 复制代码
Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
for (Thread thread : traces.keySet()) {
     System.out.println(thread.getName() + ", isDaemon = " + thread.isDaemon());
}

Thread-19, isDaemon = false

Monitor Ctrl-Break, isDaemon = true

Thread-16, isDaemon = false

Thread-18, isDaemon = false

main, isDaemon = false

Finalizer, isDaemon = true

Thread-17, isDaemon = false

Signal Dispatcher, isDaemon = true

Thread-15, isDaemon = false

Reference Handler, isDaemon = true

发现有一些守护线程,所以我对 while 的条件做了改造:

java 复制代码
while (Thread.getAllStackTraces().keySet().stream().filter((t) -> !t.isDaemon()).count() > 1) {
    Thread.yield();
}

这样程序就能够正常输出结果并退出了。

--------------########################------------------------

原示例代码使用 java 命令运行是没有问题的,只是在 IDEA 下运行会有上述问题,具体原因以及这些 daemon thread 的作用可参考这位老师的博文

另外,在第三版的该章节末尾,老师已经做了声明

相关推荐
014-code5 小时前
订单超时取消与库存回滚的完整实现(延迟任务 + 状态机)
java·开发语言
java1234_小锋6 小时前
Java高频面试题:Springboot的自动配置原理?
java·spring boot·面试
末央&7 小时前
【天机论坛】项目环境搭建和数据库设计
java·数据库
枫叶落雨2227 小时前
ShardingSphere 介绍
java
花花鱼7 小时前
Spring Security 与 Spring MVC
java·spring·mvc
言慢行善8 小时前
sqlserver模糊查询问题
java·数据库·sqlserver
专吃海绵宝宝菠萝屋的派大星8 小时前
使用Dify对接自己开发的mcp
java·服务器·前端
大数据新鸟8 小时前
操作系统之虚拟内存
java·服务器·网络
Tong Z8 小时前
常见的限流算法和实现原理
java·开发语言
凭君语未可8 小时前
Java 中的实现类是什么
java·开发语言