JAVA提供了volatile关键字,用于修饰变量。java
1.保证变量对全部线程的可见性
当一个线程修改了变量的值,会强制同步到内存,这样其它线程可以当即读取它的值。
2.禁止指令重排
经过插入内存屏障禁止CPU从新排序指令。缓存
volatile翻译为:不稳定的、易变的;
含义能够理解为:变量的值可能随时会别的线程修改,保证其它线程能读取到修改后的值。多线程
volatile能具有可见性、有序性,但不具有原子性。并发
适用场景:
线程循环标志位变量;
单例模式中的实例变量;
读多写少,写操做不依赖当前值。性能
JDK中应用:
ConcurrentHashMap的Entry的value和next被声明为volatile;
AtomicLong中的value被声明为volatile。线程
对比synchronized关键字:
volatile不具体原子性,所以不能保证多线程读写数据时数据的一致性;
但它不阻塞线程,性能高于synchronized。翻译
当对非volatile变量进行读写的时候,每一个线程先从内存拷贝变量到CPU缓存;
若是计算机有多个CPU,每一个线程可能在不一样的CPU上被处理,这意味着变量可能拷贝到不一样的CPU缓存;排序
指线程之间的可见性,一个线程修改的状态对另外一个线程是可见的。内存
指操做的最小单位,是不可分割的。
例:
原子性操做 a=0;
非原子性 a++;编译器
指令是按顺序串行执行的。 程序执行时按照代码书写的前后顺序执行; 在Java内存模型中,容许编译器和处理器对指令进行重排序; 重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。