找个图片形象一点:线程工作时候,线程对共享变量的读写都必须在自己的工作内存中进行,而不能直接在主内存中读写。不同线程不能直接访问其他线程的工作内存中的变量,线程间变量值的传递需要主内存作为桥梁。
- 线程可见性原理:
线程一对共享变量的改变想要被线程二看见,就必须执行下面两个步骤:①将工作内存1中的共享变量的改变更新到主内存中②将主内存中最新的共享变量的变化更新到工作内存2中。 - 可见性在语言层面的实现方式:synchronized 和 volatile
- Synchronized能够实现原子性(同步)和可见性。
JMM对synchronized的两条规定:线程解锁前,必须把共享变量的最新值刷新到主内存中(在推出synchronized代码块的时候,共享变量的最新值已经刷新到主内存中);线程加锁时,将清空工作内存中共享变量的值,使在使用共享变量的时候必须重新在主内存中加载最新的值(注意,加锁解锁必须用同一把锁)。这样保证了线程可见性。 - 导致线程共享变量不可见的几点原因:
线程的交叉执行,重排序加线程交叉执行,共享变量更新后的值没有在工作内存和主内存中及时更新。 - Volatile通过内存屏障和禁止重排序来实现线程可见性。但不能保证原子性
- 其实还有一种方法 final关键字声明常量,所有线程可见。