概念
java语言提供的一个关键字,用来修饰变量的,使用volatile修饰的变量可以保证并发安全的可见性和有序性。
保证可见性
使用volatile关键字修饰的共享变量,每次线程使用之前都会重新从主内存中重新读取最新的值;一旦该共享变量的值被修改了,修改它的线程比如立刻将修改后的值强制刷新回主内存。volatile的可见性是通过内存屏障来实现的。
保证指令有序性
一个有序性问题导致异常的例子
线程A执行的代码
// 步骤1
dataSource = initDataSource();
// 步骤2
httpClient = initHttpClient();
// 步骤3
initOK = true;
线程B执行的代码
// 步骤4
while(!initOK) {
}
// 步骤5
Object data = dataSource.getData();
// 步骤6
httpClient.request(data);
如果是乱序执行:由于线程A先执行了initOK = true。导致线程B提前跳出了while循环,然后线程B调用dataSource.getData的时候发现dataSource没初始化好,竟然是个坑爹的null,导致代码报错了。
initOK 加上 volatitle后分析
线程A的写分析
// 步骤1
dataSource = initDataSource(); 对应 store dataSource
// 步骤2
httpClient = initHttpClient(); 对应 store httpClient
// 步骤3
// 加上 StoreStore内存屏障,保障前面的都写了
volatitle initOK = true; 对应 store initOk = true 指令
// 加上 StoreLoad 内存屏障,保障前面的写先执行,后面的读强制读
结论
写防止重排序
StoreStore屏障
volatile-写
StoreLoad屏障
读防止重排序
LoadLoad屏障
volatitle-读
LoadStore屏障