多线程之volatile关键字

Posted cjq.java

tags:

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

现代计算机都是冯诺依曼结构的

volatile 变量具备两种特性,其一是保证该变量对所有线程可见,这里的可见性指的是当一个线程修改了变量的值,那么新的值对于其他线程是可以立即获取的。其二 volatile 禁止了指令重排。

多线程的运行可能造成变量数据的不一致

把该变量声明为volatile(不稳定的)即可,这就指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下各任务间共享的标志都应该加volatile修饰。 

Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。

synchronized开销比volatile大。

volatile不保证原子操作,所以,很容易读到脏数据。

使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。 

 

 

附录:

Happens-Before法则:

  1. 程序次序法则:线程中的每个动作A都Happens-Before于该线程中的每一个动作B,在程序中,所有的动作B都出现在动作A之后。

  2. Lock法则:对于一个Lock的解锁操作总是Happens-Before于每一个后续对该Lock的加锁操作。

  3. volatile变量法则:对于volatile变量的写入操作Happens-Before于后续对同一个变量的读操作。

  4. 线程启动法则:在一个线程里,对Thread.start()函数的调用会Happens-Before于每一个启动线程中的动作。

  5. 线程终结法则:线程中的任何动作都Happens-Before于其他线程检测到这个线程已经终结或者从Thread.join()函数调用中成功返回或者Thread.isAlive()函数返回false。

  6. 中断法则:一个线程调用另一个线程的interrupt总是Happens-Before于被中断的线程发现中断。

  7. 终结法则:一个对象的构造函数的结束总是Happens-Before于这个对象的finalizer(Java没有直接的类似C的析构函数)的开始。

  8. 传递性法则:如果A事件Happens-Before于B事件,并且B事件Happens-Before于C事件,那么A事件Happens-Before于C事件。

以上是关于多线程之volatile关键字的主要内容,如果未能解决你的问题,请参考以下文章

java多线程之volatile讲解

多线程之volatile关键字

Java多线程之synchronized和volatile的比较

JAVA多线程之volatile 与 synchronized 的比较

JAVA多线程之volatile 与 synchronized 的比较

Java——多线程高并发系列之volatile关键字