退不出的循环
先来看一个现象, main线程对run变量的修改对于t线程不可见,导致了t线程无法停止:
为什么呢?分析- -下:
1.初始状态,t 线程刚开始从主内存读取了run的值到工作内存。
3.1秒之后,main线程修改了run的值,并同步至主存,而t是从自己工作内存中的高速缓存中读取这个变量的值,结果永远是1旧值
解决方法
volatile (易变关键字)
它可以用来修饰成员变量和静态成员变量,它可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作volatile 变量都是直接操作主存。
可见性vs原子性
前面例子体现的实际就是可见性,它保证的是在多个线程之间,一个线程对 volatile变量的修改对另一个线程可见,不能保证原子性,仅用在一个写线程,多个读线程的情况:上例从字节码理解是这样的 :
比较一下之前我们将线程安全时举的例子:两个线程-一个 it+-一个i ,只能保证看到最新值,不能解决指令交错
注意synchronized语句块既可以保证代码块的原子性,也同时保证代码块内变量的可见性。但缺点是synchronized是属于重量级操作,性能相对更低
如果在前面示例的死循环中加入System.out.println()会发现即使不加volatile修饰符,线程t也能正确看到对run变量的修改了,想一想为什么?