在前面的文章里面介绍了synchronized关键字的用法,这篇主要介绍volatile关键字的用法。缓存
Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操做通知到其它线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,所以不会将该变量上的操做与其它内存操做一块儿重排序。Volatile变量不会被缓存在寄存器或者其它对处理器不可见的地方,所以在读取volatile类型的变量时,总会返回最新写入的值。多线程
volatile boolean asleep; while(!asleep){ //do something }
volatile变量一般用作某个操做完成、发生中断或者状态的标志。虽然volatile变量使用很方便,可是存在一些局限性:volatile的语义不足以确保递增操做(count++)的原子性,除非你能确保只有一个线程对变量执行写操做。spa
volatile与加锁机制的主要区别是:加锁机制既能够确保可见性又能够确保原子性,而volatile变量只有确保可见性。线程
下面以一个实例来讲明使用volatile变量做为状态标志在多线程里面的使用。code
public class VolatileTest{ volatile boolean mFlag = false; public static void main(String[] args) { final VolatileTest mVolTest = new VolatileTest(); Thread t1 = new Thread(new Runnable() { public void run() { while(!mVolTest .mFlag ){ System.out.println("Working ..."); try { Thread.sleep(1000); } catch (InterruptedException ie) { // } } } }, "t1"); Thread t2 = new Thread( new Runnable() { public void run() { try { Thread.sleep(3000); //3秒后中止线程t1 mVolTest.mFlag = true; } catch (InterruptedException ie) { // } } }, "t2"); t1.start(); t2.start(); } }
当且仅当知足如下全部条件时,才应该使用volatile变量:blog
a)对变量的写入操做不依赖变量的当前值,或者你能确保只有单个线程更新变量的值排序
b)该变量不会与其它状态变量一块儿归入不变性条件中内存
c)在访问变量时不须要加锁编译器