volatile的使用场景

Posted it馅儿包子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了volatile的使用场景相关的知识,希望对你有一定的参考价值。

单词解释:

乱序执行:指CPU对代码的执行顺序进行乱序优化,但保证各执行代码单元的顺序按指令顺序排列。以达到充分利用处理器的各处理单元的目的。(可以理解成:一个任务有不同的执行单元,这些单元之间有一定的执行顺序,但部分执行单元可提前工作乱序执行就是让这部分执行单元提前一段时间执行,从而提高整体的效率,减少整体执行时间)。

 

保证线程安全的核心要素:原子性和可见性(线程的同步机制都是围绕这两点来保证线程的安全性);

 

race condition(竞争条件):当两个以上线程读写某些共享数据,而最后的结果取决于进程进行的精确时序,称为竞争条件(race condition);

 

可见性问题出现原因:

为了协调cpu和内存读写速度巨大差异的问题,所以有了高速缓存的出现(cpu不会每次获取数据都从内存获取,而是在高速缓存中存储有拷贝),但同时产生了可见性问题(由于cpu对内存中的对象的读取并不是原子操作,所以线程a拿到的对象并不一定是线程b写入的对象,此处有乱序执行的影响,但不止此因素)。

 

上一篇讲了volatile的特性,如下是volatile的使用条件:

volatile只能保证操作的可见性,但无法保证操作的原子性,所以使用条件会比synchronized苛刻,如下(必须同时满足):

1.更改不依赖于当前值,或能够确保只会在单一线程中修改变量的值,如果对变量的修改依赖于现有值,就是一个race condition操作,此时就需要使用其它方式了(比如synchronized),volatile对原子性的问题发能为力。

2.变量不需要和其他变量共同参与不变约束,比如start<end ,即使start和end都被标识为volatile,但当存在多个线程同时存在时,仍存在线程安全问题:

  检查start<end是否成立, 在给start赋值之前不变式是有效的。

  但是如果另外的线程在给start赋值之后给end赋值之前时检查start<end, 该不变式是无效的。

 

 

volatile的典型使用场景是作为标记使用:

public class SocketThread extends Thread {

public volatile boolean running = true;

@Override

public void run() {


while (running) {



// ...


}

}
}

 

以上是关于volatile的使用场景的主要内容,如果未能解决你的问题,请参考以下文章

volatile的适用场景

volatile的适用场景

java volatile关键字

volatile的含义及使用场景

volatile原理和使用场景

Java volatile关键字解惑