上篇博客中主要介绍了,多线程中内存可见性的实现原理,主要是从jmm的角度去解释了实现原理。同时也引出了如果要实现共享变量的可见性,必须保证两点:
1.线程修改后的共享变量值能够及时从工作内存刷新到主内存中。
2.其他线程能够及时把共享变量的最新值从主内存中更新到自己的工作内存中。
这篇博客根据实现共享变量的可见性的思想原理,总结一下实习这种思想的两种方式。
1.synchronized
1.1JMM关于synchronized的两条规定:
1.解锁前,必须把共享变量的最新值刷新到内存中。
2.线程加锁前,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值。
1.2synchronized执行过程
1.获取互斥锁.
2.清空工作内存。
3.从主内存拷贝变量的最新副本到工作内存中。
4.执行代码
5.将更改后的共享变量的值刷新的内存中。
6.释放互斥锁。
1.3影响内存可见性的两个内容:
指令重排序:
代码书写的顺序与实际执行的顺序不同,指定重排序是编译器或处理器为了提高性能而做的优化。
1.编译器优化的重排序
2.指令集并行重排序
3.内存系统的重排序
as-if-serial
无论如何重排序,程序执行的结果都应该与代码的顺序执行结果一致。
2.volatile
通过加入内存屏障和禁止重排序优化来实现。
1.对volatile变量执行写操作时,会在写操作后加入一条store屏障指令
2.对volatile变量指向读操作时,会在读操作前加入一条load屏蔽指令。
2.1volatile如何实现内存可见性
volatile变量在每次被线程访问时,都强迫主内存中重读该变量的值,而该变量发生变化时,又会强迫线程将最新的值刷新到主内存。这样任何时刻,不同的线程总能看到该变量的最新值。
线程写volatile变量的过程
1.改变线程工作内存中volatile变量副本的值。
2.将改变后的副本的值从工作内存中刷新到新的内存中。
线程读volatile变量的过程
1.从主内存中读取volatile变量的最新值到线程的工作内存中。
2.从工作内存中读取volatile变量副本。