忽隐忽现

天道酬勤

导航

【Multiple-Thread】有关volatile(易失字段)

Posted on 2010-03-07 18:37  忽隐忽现  阅读(518)  评论(0)    收藏  举报
  定义

当在声明值类型字段时使用 volatile 修饰符,就称该字段为易失字段。

例如:public vollatile int counter = 0;

  背景

为了加快CPU处理速度,编译器会对指令进行优化,将变量值在寄存器中缓存,下一次使用时就直接读取这个缓存而不是内存,

单线程应用程序受益于这个技术,在确保正确运行的前提下提高了运行速度;但是在多线程应用程序中,则可能由于这个CPU优

化技术导致从缓存中读取的是脏数据,从而导致应用程序Bug。

  示例

class Demo

{

     public int counter = 0;

}

Demo obj = new Demo();

我们假设这个Demo类的实例obj会被多个线程进行读写操作,又由于达到了编译器的优化条件,每个线程都会在寄存器中缓存一个

obj中的公开字段counter的副本。

这时,线程A修改了counter,线程B又对counter进行了读或写,但B仍使用的是最初counter的值,无法读取到counter的最新值,

因为每个线程读取的来源和更改的目标都是自己缓存下了的那个值。

这样Bug便产生了。

  解决

使用 volatile 修饰符能够保证该字段不被缓存到CPU寄存器中,从而每个线程都能够对这个字段的实际内存进行“即时”的读写:

一个线程对易失字段做了更改,便会立即反映到该字段的实际内存地址中,而其他线程对易失字段进行读取的时候,也是直接从该

字段的实际内存地址中获取值的。

换句话说,任何线程中改变了易失字段的值,所有其他线程立即获取到了其最新值。

 

我们在多线程应用程序开发中,千万不要忘记在能被多个线程共享的值类型变量前面加上个vollatile修饰符啊!