测试 volatile 用法时,一直感觉有无voletile,结果是相同的,每个线程都可以看见变更已经改变了。原码如下
public class VolatileTest implements Runnable
{
boolean flag = false;
int i = 0;
@Override
public void run()
{
while (!flag)
{
i++;
System.out.println( i );
}
}
public static void main(String[] args)
throws Exception
{
VolatileTest vt = new VolatileTest();
new Thread(vt).start();
Thread.sleep(100);
vt.flag = true;
System.out.println( "stop");
}
}
但是又觉得哪里有问题。后来偶然发现如果把while循环中的 System.out.println( i ); 拿掉,就有区别了。原来是System.out.println( i ) 影响了变更的可见性。pirntln原码:
public void println(String x)
{
synchronized (this)
{
print(x);
newLine();
}
}
原来println有一个上锁的操作。使用了 synchronized 上锁会做以下操作:
- 获得同步锁;
- 清空工作内存;
- 从主内存拷贝对象副本到工作内存;
- 执行代码(计算或者输出等);
- 刷新主内存数据;
- 释放同步锁。
so so so。。。。。。。。