写写JMM吧,曾经我还傻傻的以为是谁把JVM写错了
我是
方圆
,循序渐进,按部就班
1. 什么是JMM呀?
JMM是Java Memory Mode
的缩写,译成中文是Java内存模型。它定义了Java虚拟机在计算机内存中的工作方式,JMM是隶属于JVM的。
从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系
,线程之间的共享变量存储于主内存中,每个线程又都有自己的工作内存。而实际上,工作内存并不存在,仅仅是一个抽象的概念,它涵盖了缓存、写缓冲区、寄存器及其他的硬件和编译器优化。
2. JVM对Java内存模型的实现
- 在JVM内部,Java内存模型把内存分成了两部分,
线程栈区和堆区
JVM中运行的每条线程都有自己的线程栈
,线程栈包含了当前线程执行的方法调用相关信息,我们也把它叫做调用栈。
3. JMM带来的问题
-
可见性问题
不同线程从主内存中获取值,并存储在自己的工作内存中。若对工作内存的进行修改之后,没有及时将其flush到主内存中,这就导致了不同线程中共享变量值不同的问题。(可以通过加锁和关键字volatile解决) -
竞争问题
线程A和线程B共享一个对象obj。假设线程A从主存读取Obj.count变量到自己的CPU缓存,同时,线程B也读取了Obj.count变量到它的CPU缓存,并且这两个线程都对Obj.count做了加1操作。此时,Obj.count加1操作被执行了两次,不过都在不同的CPU缓存中。如果这两个加1操作是串行执行
的,那么Obj.count变量便会在原始值上加2,最终主存中的Obj.count的值会是3。然而下图中两个加1操作是并行的
,不管是线程A还是线程B先flush计算结果到主存,最终主存中的Obj.count只会增加1次变成2,尽管一共有两次加1操作。 (解决上面的问题我们可以使用java synchronized代码块)