首页 > 代码库 > Java内存模型学习笔记
Java内存模型学习笔记
Java内存模型(JMM):描述了java程序中各种变量(线程共享变量)的范根规则,以及在JVM中将变量存储到内存和从内存中读取出变量这样的底层细节。共享变量就是指一个线程中的变量在其他线程中也是可见的。
共享变量可见性的实现:假设目前有两个线程:线程1和线程2。线程1的读取主内存的x=0到线程1的工作内存中,并执行将x=1操作;主内存会将x的最新值更新过来,即x=1;最后线程2的工作内存会将主内存的最新值更新过来。
共享内存可见性的实现方式:synchronized实现和volatile实现
1.synchronized实现:
①线程解锁前,必须把共享变量的最新值刷新到主内存中;
②线程加锁时,将清空工作内容中的共享变量的值,从而使用共享变量需要从主内从中重新读取最新的值(注意:加锁与解锁需要同一把锁)
也就是说,线程解锁前对共享变量的修改,在下次加载时对其他线程也可见。线程执行互斥代码的过程如下:
1??获得互斥??
2??清空工作内存
3??从主内存拷贝变量的最新值副本到工作内存
④执行代码
5??将更新后的共享变量值刷新到主内存中
6??释放互斥??
PS:重排序 和 as-if-serial
(1)重排序就是代码书写的顺序与实现执行的顺序不同。指令重排序是编译器或处理器为了提高程序性能而做的优化
1??编译器优化重排序(编译器优化);
2??指令级并行重排序(处理器优化);
3??内存系统重排序(处理器优化)
(2)as-if-serial就是无论如何重排序,程序执行代码的结果都和顺序执行的相同。
在单线程中,重排序不影响内存的可见性。但是在多线程中,重排序可能会影响内存的可见性。具体如下:
①线程的交叉执行--------------------------------------------------------------------------------------原子性
②重排序结合线程的交叉执行--------------------------------------------------------------------------原子性
③共享变量更新后没及时在主内存更新-----------------------------------------------------------------可见性
△synchronized解决方案:锁 + 原子性
△volatile的解决方案:实现可见性,但是不能保证原子性。
volatile的可见性实现:内存屏障和禁止重排序优化。
1??对volatile变量执行写操作时,会在写操作后加入一条store屏障指令;
2??对volatile变量执行读操作时,会在读操作后加入一条load屏障指令;
volatile变量在每次被线程访问时,都强迫从主内存中重读该变量的值,而当该变量发生变化时,又会强迫线程将最新的值更新到主内存中,这样任何时刻,不同线程总能看到该变量的最新值。
Java内存模型学习笔记