这个是面试高频题
首先上代码看一下volatile的作用
public class JMMTest {
private boolean flag = false;
public static void main(String[] args) throws Exception {
final JMMTest jmmTest = new JMMTest();
//实现Runable接口 使用匿名内部类简化代码
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread1--start");
while (!jmmTest.flag){
}
System.out.println("thread1--end");
}
}).start();
Thread.sleep(100);
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread2--start");
jmmTest.flag=true;
System.out.println("thead2---end");
}
}).start();
}
}
上面代码的运行结果是
线程1无法感知到看到线程2对共享变量flag的改变,所以!jmmTest.flag一直是初始值true,所以就无限的循环
当给变量falg加上valotile关键字的时候运行结果是这样的
说明在加volatile之后线程1就能感知到看到线程2对共享变量的改变,然而进行相关的判断操作
结论
//主内存中 解决不同线程之间的可见性 缓存一致性协议 缓存一致性问题 总线嗅探机制的监听
//1 lock指令 汇编指令
//2 强制修改的值写入主内存
//3 当写操作的时候,其它线程对应的cpu缓存暂时失效
volatile的作用和syncornized的区别主要有两点
1:valotile只能作用于变量,而syncornized可以作用于变量和方法
2:volitle只能保证数据的可见性,不能保证原子性,syncornized既可以保证数据的可见性,在多线程下还可以保证原子性(即原子性)