effective java第66条,同步访问共享变量的一个例子
例如
public class VolatileTest {
private static boolean testBool;
public static void main(String[] args) throws InterruptedException {
Thread test = new Thread(new Runnable(){
public void run(){
int i = 0;
while(!testBool){
i++;
}
}
});
test.start();
TimeUnit.SECONDS.sleep(1);
testBool = true;
}
}
书中说虚拟机会将代码优化hoisting
if(!testBool){
while(true) i++
}
而导致该进程操作无法停止
可以使用sync关键字同步读写testBool变量,从而达想要的通信效果
也可以使用volatile修饰符修饰testBool,该修饰符会强制线程复制的共享变量值一直为共享池中的最新值。
但是如果JVM仍然进行hoisting优化,效果应该是不正确的。而实际效果是正确的。可能是volatile修饰符强行终止了JVM优化。
volatile并不能实现同步互斥,只是让线程一直获取最新的共享内容,只能保证对单次读/写的原子性,像i++这种操作是读和写两次操作,读取i,对i+1,写入i。
测试发现,在i++后执行一个System.out.println("i" + i);内容也会发生VM没有进行优化操作,代码在主线程执行完赋值就终止了。
而且翻阅网络上的文章,发现VM使用client模式也不会复现优化后的场景,只有server模式VM才可以复现