码迷,mamicode.com
首页 > 其他好文 > 详细

Volatile详解

时间:2020-05-05 20:03:37      阅读:54      评论:0      收藏:0      [点我收藏+]

标签:inf   程序   incr   vol   mamicode   方式   thread   退出   false   

一,.volatile关键字的两层语义:

(一),一旦一个共享变量被volatile修饰之后,那么就具备了两层语义:

  1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

  2)禁止进行指令重排序。

 (二),内存屏障有两个能力:

      1. 阻止屏障两边的指令重排序

      2. 强制把写缓冲区/高速缓存中的脏数据等写回主内存,让缓存中相应的数据失效

 (三),volatile只保证可见性,不保证原子性;

  volatile方式的i++,总共是四个步骤:

  Load、Increment、Store、Memory Barriers。

(四)下面程序是:主线程修改非volatile类型的全局变量flag,子线程轮询flag,如果flag发生变动,则程序退出。但是如果实际运行这段代码会造成死循环,程序无法正常退出。这个现象是由于flag变量不是volatile的,主线程对flag的修改不一定能被子线程看到而引起的。

public class VisibilityDemo {
    private volatile   boolean flag=true;
    //private   boolean flag=true;
    
//-server -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:+LogCompilation -XX:LogFile=jit.log
    public static void main(String[] args) throws InterruptedException {
        VisibilityDemo demo1=new VisibilityDemo();
        new Thread(new Runnable() {
            @Override
            public void run() {
                int i=0;
                System.out.println(Thread.currentThread().getName());
                while(demo1.flag){
                    synchronized (this){

                        i++;

                    }
                }
                System.out.println(i);
            }
        }).start();
//        System.out.println("即将sleep的Thread是:"+Thread.currentThread().getName());
        TimeUnit.SECONDS.sleep(2);
        demo1.flag=false;
        System.out.println("被置为false了");
    }
}

加上volatile之后,程序正常退出,通过javap命令查看,有ACC_volatile命令,意思是禁止缓存。

遵循Happens-before原则。

技术图片

 

Volatile详解

标签:inf   程序   incr   vol   mamicode   方式   thread   退出   false   

原文地址:https://www.cnblogs.com/boogie-xy/p/12831852.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!