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 的作用可参考这位老师的博文

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

相关推荐
汝生淮南吾在北1 小时前
SpringBoot+Vue饭店点餐管理系统
java·vue.js·spring boot·毕业设计·毕设
冬夜戏雪4 小时前
【java学习日记】【2025.12.7】【7/60】
java·开发语言·学习
CC.GG4 小时前
【C++】二叉搜索树
java·c++·redis
JIngJaneIL6 小时前
基于Java非遗传承文化管理系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot
南部余额6 小时前
踩坑与解惑:深入理解 SpringBoot 自动配置原理与配置排除机制
java·spring boot·自动配置原理·import
木鹅.7 小时前
LangChain4j
java
永远都不秃头的程序员(互关)8 小时前
Java核心技术精要:高效实践指南
java·开发语言·性能优化
CoderYanger8 小时前
动态规划算法-子序列问题(数组中不连续的一段):28.摆动序列
java·算法·leetcode·动态规划·1024程序员节
代码栈上的思考8 小时前
深入解析Spring IoC核心与关键注解
java·后端·spring
Mai Dang8 小时前
SpringBoot4用Swagger
java