背景
学了六年C#,一直没有使用过 volatile,对多线程编程也是偶尔才会使用,这次学习 Java 又遇到了 volatile,准备稍微深入的了解一下。
volatile 的作用?
几乎所有支持这个关键字的语言给出的解释都一样:阻止编译器对字段访问和赋值的优化,直接从字段所在的空间取值(可能是值,也可能是引用),而非引入寄存器等优化措施(跟编译器的实现有关)。
使用 volatile 后对,字段的访问(this.field)和字段的赋值(this.filed = xxx)就是原子操作了,在多线程环境下,不需要使用 synchronized 进行访问,否则的话必须使用 synchronized 进行访问。
何时使用 volatile?
根据上文,我们很容易总结出一个规律:方法中只对字段就行了访问或赋值,volatile 和 synchronized可以结合使用,如下例:
1 public class Program { 2 static Object locked = new Object(); 3 static volatile int count; 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 8 9 } 10 11 static int getCount() { 12 return count; 13 } 14 15 static void resetCount() { 16 count = 1; 17 } 18 19 static void increaseCount() { 20 synchronized (locked) { 21 count++; 22 } 23 } 24 }
备注
本文没有深入到编译后的字节码级别进行探讨(也有可能是影响JIT),所以不一定对,有深入了解的朋友,还请留言批评。