初识JMM
1、什么是JMM
Java 内存模型,是一种抽象的概念并不真实存在,它描述的是一组规则或规范;
2、做什么的
通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式;
3、怎么玩
3.1 定义线程和主内存之间的抽象关系
线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在,它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。Java内存模型的抽象示意图如下:
线程间通信的步骤:
- 首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去。
- 然后,线程B到主内存中去读取线程A之前已更新过的共享变量。
3.2 可见性、有序性
可见性:当一个对象在多个内存中都存在副本时,如果一个内存修改了共享变量,其它线程也应该能够看到被修改后的值;
有序性:A线程负责取款,B线程负责汇款,A从主内存读到100,B从主内存读到100,A执行减10操作,并将数据刷新到主内存,这时主内存数据100-10=90,而B内存执行加10操作,并将数据刷新到主内存,最后主内存数据100+10=110,显然这是一个严重的问题,我们要保证A线程和B线程有序执行,先取款后汇款或者先汇款后取款,此为有序性。
3.3 synchronized与volatile
一个线程执行互斥代码过程如下:
- 获得同步锁;
- 清空工作内存;
- 从主内存拷贝对象副本到工作内存;
- 执行代码(计算或者输出等);
- 刷新主内存数据;
- 释放同步锁。
所以,synchronized既保证了多线程的并发有序性,又保证了多线程的内存可见性。
volatile是第二种Java多线程同步的手段,一个变量可以被volatile修饰,在这种情况下内存模型确保所有线程可以看到一致的变量值。volatile可以保证内存可见性,不能保证并发有序性。
4、重排序(略)
参考链接:
AlphaWang 原创【Java线程】Java内存模型总结