zoukankan      html  css  js  c++  java
  • 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原则。

  • 相关阅读:
    使用virtualenv搭建python3的环境
    Linux/unix inode
    转:进程间通信方式
    保研复试上机——数据库
    转:mysql grant
    mysql 查询结果创建表
    279. Perfect Squares
    Mybatis中javaType和jdbcType对应和CRUD例子
    mysql explain
    91. Decode Ways
  • 原文地址:https://www.cnblogs.com/boogie-xy/p/12831852.html
Copyright © 2011-2022 走看看