云时代的 JVM 原理与实战
康杨
京东资深架构师
3111 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 39 讲
云时代的 JVM 原理与实战
15
15
1.0x
00:00/00:00
登录|注册

20|JMM:如何打造一个线程安全的程序?

你好,我是康杨。
在编程过程中,你有没有遇到过在运行多线程程序时想用共享变量来通讯,却发现程序结果和预期不一致的情况?这个常见的问题就是多线程编程的难点,涉及内存可见性和重排等问题。今天我们就来解决这些问题,并探讨 JVM 如何通过它的内存模型 JMM 来解决它们。

可见性问题

第一个问题出现在处理器和内存之间。现代电脑系统中,处理器速度很快,内存的读写速度却远远不能比肩。为了解决这种矛盾,引入了高速缓存,处理器将计算所需数据复制到缓存,从而加快运算速度。然而,这也引发了缓存的一致性问题,也就是说,在多处理器系统里,如果每个处理器都同时使用相同的内存,那么它们的缓存数据可能会出现差异。
处理器必须按照一些协议进行同步操作,在读写时维持缓存一致性。这里就涉及到内存可见性问题,也就是一个线程修改的状态能够即时在其他线程中可见

重排问题

我们日常写的代码,在实际运行之前,都会经过 JVM 及底层 CPU 等各种优化,来达到最优的执行性能。但是这种优化都是基于单线程考虑的优化,如果你的程序是以多线程的方式运行,反而很容易引发各种问题。所以对于多线程的程序,知道 JVM 实际进行了哪些优化非常重要。
指令序列从源代码到实际执行的过程可能会经历以下三种重新排序。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Java内存模型(JMM)是多线程编程中的关键概念,旨在解决内存可见性和指令重排等问题。JMM基于主内存和工作内存的交互操作,以及指令重排等优化规则,确保多线程环境下的内存可见性和操作顺序一致性。为了构建线程安全的程序,开发者可以利用JMM提供的解决方案,如Synchronized关键字、Volatile关键字、final关键字、Lock接口和原子变量等。这些解决方案能够保证共享变量的可见性、有序性和原子性,从而避免多线程并发中的问题。通过熟练掌握JMM的基本原理和内存间的交互操作,开发者能够更好地构建线程安全的Java程序。因此,JMM为多线程编程提供了重要的指导原则,帮助开发者避免内存可见性和重排问题,确保程序在多线程环境下的正确性。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《云时代的 JVM 原理与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(1)

  • 最新
  • 精选
  • peter
    请教老师几个问题: Q1:编译器重排的例子,怎么禁止编译器重排列? Q2:指令并行重排的例子,指令并行,是指“a = 1”和“flag = true”这两个指令并行处理,而且并行处理的时候,“flag = true”比“a = 1”先执行吗? 另外,while (!flag),是不是多加了一个“!”?“重叠执行”就是指并行执行吗? Q3:缓存系统的重排,“处理器利用了缓存以及读写缓冲区”这句话中,“缓存”是指CPU缓存吗?“读写缓冲区”又是指什么?“负载和保存的任务”,这句话中,“负载任务”和“保存任务”分别指什么? Q4:JVM,主内存和工作内存部分。假设系统物理内存是100M,不考虑操作系统和其他应用,假设有两个进程A和B,A用10M内存,B用20M内存,那剩下的70M内存就是主内存吗? Q5:“当某个进程对某一变量进行读取或修改操作的时候,需要先把相关数据从主存搬到工作区,完成后又需要把改动后的内容重新拷贝回主存。”,对于某个进程,对于所有的变量修改都需要这样操作吗?还是只针对某些变量?
    2023-10-15归属地:北京
收起评论
显示
设置
留言
1
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部