听说在Java 5之前volatile关键字备受争议,所以本文也不讨论1.5版本之前的volatile。本文主要针对1.5后即JSR-133针对volatile做了强化后的了解。
二 volatile的特性开门见山,volatile变量自身具有以下特性:
可见性(最重要的特性)。对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
原子性。对任意(包括64位long类型和double类型)单个volatile变量的读/写具有原子性。但是类型于a++这种复合操作不具有原子性。
下面通过案例来证明下可见性,先看一个普通变量是否能保证可见性:
3 class Example { 4 private boolean stop = false; 5 public void execute() { 6 int i = 0; 7 System.out.println("thread1 start loop."); 8 while(!getStop()) { 9 i++; 10 } 11 System.out.println("thread1 finish loop,i=" + i); 12 } 13 public boolean getStop() { 14 return stop; // 对普通变量的读 15 } 16 public void setStop(boolean flag) { 17 this.stop = flag; // 对普通变量的写 18 } 19 } 20 public class VolatileExample { 21 public static void main(String[] args) throws Exception { 22 final Example example = new Example(); 23 Thread t1 = new Thread(new Runnable() { 24 @Override 25 public void run() { 26 example.execute(); 27 } 28 }); 29 t1.start(); 30 31 Thread.sleep(1000); 32 System.out.println("主线程即将置stop值为true..."); 33 example.setStop(true); 34 System.out.println("主线程已将stop值为:" + example.getStop()); 35 System.out.println("主线程等待线程1执行完..."); 36 37 t1.join(); 38 System.out.println("线程1已执行完毕,整个流程结束..."); 39 } 40 }