• Volatile详解


    一,.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原则。

  • 相关阅读:
    TouchAction实现连续滑动设置手势密码
    用命令方式启动、停止appium服务和app
    企业软件防火墙iptables
    磁盘分区
    docker-网络
    docker-镜像管理基础
    docker-简单操作
    docker-安装
    python-函数
    find一些常用参数的一些常用实例和一些具体用法和注意事项。
  • 原文地址:https://www.cnblogs.com/boogie-xy/p/12831852.html
Copyright © 2020-2023  润新知