当前位置: 首页 > news >正文

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

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

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 的线程打印出来:

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 的条件做了改造:

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

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

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

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

另外,在第三版的该章节末尾,老师已经做了声明在这里插入图片描述

http://www.lryc.cn/news/277844.html

相关文章:

  • GPM合并资料整理-GEM部分
  • STM32使用1.69寸液晶显示模块使用缓冲区实现快速刷新全屏显示字符串功能
  • SpringBoot AOP
  • 鉴源论坛 · 观模丨浅谈Web渗透之信息收集(下)
  • 构建自己的私人GPT-支持中文
  • php将文本内容写入一个文件(面向过程写法)
  • SPDK As IPU Firmware
  • 快速删除node_modules文件夹
  • Mac安装nvm以及使用nvm安装node
  • vue element-ui的table列表中展示缩略图片效果实例
  • C/C++动态内存管理
  • 矩阵中的最长递增路径
  • vue2 element 弹出框拖拽会出现一层阴影问题
  • idea git回滚之前提交记录
  • 什么是Modbus协议?
  • 222.【2023年华为OD机试真题(C卷)】分配土地(扫描线算法-JavaPythonC++JS实现)
  • Linux网络编程(一-网络相关知识点)
  • IO进程线程day5
  • 读元宇宙改变一切笔记04_网络化
  • 用Promise实现util函数
  • 使用numpy处理图片——白色背景变全透明
  • 计算机网络层之ICMP与IGMP
  • FlinkAPI开发之自定义函数UDF
  • 阿里云国际服务器设置安全防护程序
  • C++获取内存使用情况
  • CRMEB多商户短信开发
  • Leetcode 1049 最后一块石头的重量II
  • 【设计模式之美】SOLID 原则之二:开闭原则方法论、开闭原则如何取舍
  • Kafka 基本概念和术语
  • 【每日面试题】Docker常见面试题精选