volatile关键字,几乎是面试必问的话题,但是我浏览了所有的网页并没有发现正确清晰的例子。都是一些概念上的解答,本文通过一个测试过的Java实例,来讲解volatile关键字的用法和场景。
1.概念
我也先简单讲一下概念,让初学者有点了解。并发,有可见性和原子性两种。volatile只保证了可见性遵循happen-before原则,不保证原子性。所以这个关键字不能作为计数器使用(计数器取值,+1,赋值,3步操作)。可见性主要是保证每次都去内存中取变量值,不在高速缓冲寄存器中进行取值,保证不会发生值改变,你使用的时候有没有改变。
2.网上说法
先说几个网上的实例,这是网上最常见实例,也是权威书籍《并发编程实践》的例子,但是我测试多次并没有发生问题。
网上对此有两种解释,一种是指令重排序无法确定是否是read先赋值,还是num先赋值。另一种,是jvm在server模式下。线程会复制原对象信息放到栈中,所以不会读取到read赋值为true,会发生死循环。以上两种都没有发生。
package com.ldh.valid;
/**
* 并发编程中,因为指令重排序会出现 0,死循环。
* 单机i5,4核,无异常
* @author liudonghe
*
*/
public class Vol2 extends Thread{
//测试不加volatile关键字
private static volatile boolean read;
private static int num;
@Override
public void run() {
while(!read){
yield();