什么是可见性?多线程
在我理解就是多线程下,当一个线程修改共享变量时,其余线程可以及时的获得修改的值,此为可见性。jvm
具体的描述下,线程1,2启动后,从主内存读取值x=0,而后以副本的形式存到各自线程的工做内存中。而后线程1的x=1后,若是线程2在使用x的时候能从新从主内存中读取x=1,那么这就是可见性。线程
那么咱们确定须要必定的手段来保证这个顺序(工做内存1 - 主内存 - 工做内存2),排序
如何保证?内存
1,线程在修改共享变量后,须要及时回刷主存it
2,其余线程在使用共享变量时,副本变量应被清空,去主内存从新读取。变量
那么如何作到?原理
jvm的内置锁,synchronized程序
synchronized原理是,解锁前,将共享变量回刷主存,在加锁时清空工做内存的共享变量,去主存从新读取。同时加锁避免了指令重排序致使的问题。方法
那么既然加锁,那么首先程序已经变成了串行,那么很好理解可见性。可是jvm还提供了一种轻量级的变量修饰符volitile(不能保证非原子性的操做)
可是其实还有一个更轻量级的修饰符volatile
他也能够保证内存的可见性(只支持原子操做,不支持复杂操做如i++),他的原理主要靠的是内存屏障
当读volitile变量时,加一条load屏障,让副本的变量失效
当写volitile变量时,会加一条store屏障,让变量直接回刷主存,不会等到方法结束