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

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

相关推荐
程序猿乐锅2 小时前
从0-1一文详解RabbitMQ
java·分布式·后端·中间件·rabbitmq·ruby
考虑考虑5 小时前
JDK26中的List.ofLazy()
java·后端·java ee
小蒜学长6 小时前
基于SpringBoot的公寓报修管理系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·公寓报修管理系统·多角色协同
for_ever_love__6 小时前
MySQL 主从复制讲透:binlog 原理、搭建步骤与读写分离
java·数据库·mysql·binlog·读写分离·原理·主从复制
小π军8 小时前
操作系统面试题
java·linux·服务器
倔强的石头1069 小时前
应用账号最小权限实践:读写账号、报表账号、运维账号分层
java·运维·开发语言
Shaoshing9 小时前
ThreadLocal
java·jvm·threadlocal
写后端的胖头鱼9 小时前
一文详解CAS
java·jvm·spring·cas·乐观锁·自旋
鱼宵9 小时前
Spring AI 提示词模板:{变量} 参数化 + few-shot,一条提示词反复用
java·人工智能·spring·few-shot·提示词工程·springai