哈喽,我是子牙。十余年技术生涯,一路披荆斩棘从技术小白到技术总监到JVM专家到创业。技术栈如汇编、C语言、C++、Windows内核、Linux内核。特别喜欢研究虚拟机底层实现,对JVM有深入研究。分享的文章偏硬核,很硬的那种。
手撸过JVM、内存池、垃圾回收算法、synchronized、线程池、NIO、三色标记算法…
今天给大家分享一篇对于理解Java的多线程,特别重要的一个知识点:JMM。
在JVM中增加线程机制,首当其冲就是要实现JMM,即Java内存模型。JMM也是大家真正理解Java多线程的基础。但是大家对于JMM,可以说大多数小伙伴对其的理解是错误的。这篇文章我会从这几个方面讲JMM,让大家获得对JMM正确的、深刻的认识:
1、市面上大家看到的资料是怎么介绍JMM的
2、我会结合一个Linux多线程程序给大家分析,JMM与MESI没有半毛钱关系
3、那为什么要有JMM?不要行不行?
4、Java代码加或不加volatile对于可见性的影响如何理解?
正确认识JMM
有些小伙伴可能第一次听说JMM,大概介绍下:JMM即Java内存模型,不是JVM内存模型。Java的多线程机制是基于JMM实现的。如果你第一次听到这玩意是通过我这篇文章,那恭喜你,你还没有中毒。如果你还想进一步了解,接着往后看。
MESI即CPU的缓存一致性协议。现在取而代之的是MOESI。不同架构的CPU还有可能用其他的协议。理解本篇文章,了解到这个程度就够了,不展开讲。感兴趣的小伙伴可以自行面向百度学习。
你现在百度搜JMM,展示的文章基本都是这个套路:CPU缓存架构、计算机的内存模型、MESI、volatile实时触发数据一致性……不知道这套思路的始祖是谁,把一个简单的JMM讲得复杂得不行,正常人根本就看不懂,甚至被劝退。关键是错的,还能自圆其说地把这些名词串起来讲得像是真的一样。有多少小伙伴有同感的,留言区举个爪。
那如何正确理解JMM呢?一、不要把它与什么CPU、OS内存模型扯上关系。这些区域的数据一致性与JMM无关。可以想象有一堵墙,墙的一边是OS及硬件,另一边是JVM。JMM只与JVM有关,手没那么长,伸不到墙那边去;二、JMM你可以直接把它理解成工作内存+主内存;三、加或不加volatile跟触发MESI没有半毛钱关系,只是让JVM知道我要不要回写,伪代码如下
因为JMM是JVM自己抽象实现的,如果发生了写操作,正常情况工作内存与主内存的数据是不一致的。如果想告诉JVM我需要它一致,就得提供一套机制,这个机制就是volatile的一部分功能。
有两个名词解释一下:主内存,即共享内存,等同于JVM内存模型中的方法区+堆区。工作内存,即私有内存,等同于JVM内存模型中的虚拟机栈。
有些小伙伴可能就要说了:这些都是子牙老师你的个人认识,我们怎么知道是你的正确还是网上的那套呢?是的,没毛病(疯狂记仇)。熟悉我的小伙伴都知道,我要开始上证据了。名声稳不稳得住,就看证据给不给力了,求不翻车。
这个怎么解释
咱们来反证:如果CPU间的缓存一致、CPU缓存与内存间的数据一致需要通过volatile来触发,那操作系统线程间的数据可见性怎么触发?我们会写代码手动触发吗?上一段程序让大家感受下。
代码中没有任何触发机制,大家猜下:线程一sleep前后输出的结果是否都是10?上答案
答案是这次修改是线程可见的。为什么OS的线程天生具备线程可见性,而JMM不具备呢?这个画图不好说明,我将录制成视频放在B站。如果你没想明白,你想搞清楚,可以识别下方二维码观看。OS的线程可见性需要借助汇编说明。视频录制需要点时间,我会尽快录制的。
我感觉那些把JMM与MESI扯在一起的所谓大神,对底层真的一无所知。你但凡写个操作系统级别的多线程程序一测,就知道MESI还需要通过应用程序来触发,那是多么滑稽的一件事情。就像手机没有待机功能那么滑稽。
为什么要有JMM
同样来反证:不要JMM行不行?行?不行?答案是行!但是如果没有JMM,JVM就无法跨平台了,需要针对特定架构的操作系统开发线程机制。而且目前很多借助虚拟机栈实现的机制,比如synchronized的轻量级锁,可能实现起来就要更复杂一些了。
如果我们自己写程序,只针对特定的操作系统,比如Ubuntu,那不抽象实现JMM,直接基于操作系统的线程机制实现,会非常简单。但是我的手写JVM小班实现线程机制,还是与JVM保持一致,抽象实现了JMM。这样写一遍,将自己放在设计者的角度去思考,对于你阅读hotspot源码,会更有利。直接基于操作系统的线程机制去实现,好奇心重的小伙伴可以写一写,或许你能从中获得不一样的认知呢!
问个问题,看大家对本篇文章的内容理解得怎么样:那JMM与MESI可不可以有关系呢?大家留言回答吧。
我是子牙老师,喜欢钻研底层,深入研究Windows、Linux内核、JVM。如果你也喜欢研究底层,欢迎关注我的公众号【硬核子牙】