volatile关键字

volatile是jvm的轻量级同步机制

  • 保证可见性
  • 不保证原子性
  • 禁止指令重排

保证可见性

下属程序A线程运行时会出现死循环:

private static boolean flag = true;
public static void main(String[] args) {
    Thread A =  new Thread(()->{
        while (flag){
        }
    });
    A.start();
    try {
        TimeUnit.SECONDS.sleep(3);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    flag = false;
}

并不会因为flag的改变而停止,原因观察上图,flag 改变A线程并不知道

加上volatile后,线程A会可见flag的改变,解决问题

private volatile static boolean flag = true;

不保证原子性

原子性:不可分割,某任务执行,不能被打扰分隔,要么同时成功要么同时失败

以下实例的结果不是2w, 说明他不保证原子性

private volatile static int  number = 0;
public static void main(String[] args) {
    for (int i = 0; i < 20; i++) {
        new Thread(()->{
            for (int j = 0; j < 1000; j++) {
                add();
            }
        }
        ).start();
    }
    while (Thread.activeCount()>2){//main gc
        Thread.yield();
    }
    System.out.println(number);
}
public static void add(){
    number++;
}

想要保证原子性,可以使用原子类AtomicInteger

number.getAndIncrement() // +1

指令重拍

计算机可能不会按照你的写的那样运行程序: 源代码 -> 编译器优化重排 -> 内存系统也会重排 -> 执行。但是 volatile 可以保证指令的顺序,不被重排

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容