zoukankan      html  css  js  c++  java
  • volatile关键字

     volatile保证可见性,防止指令重排序

    参考文献  https://www.cnblogs.com/xll1025/p/6486170.html

    相关知识点.

    一、happen-before可见性原则   

    1.线程之间(访问共享数据)可见性共享,2锁,解锁后可见性hapen-before需要锁的线程;

    3. volatile 被他修饰的数据,可见性写的动作happen-before 读的线程4,传递性A线程hapen-before B线程,B线程hapen-beforeC线程,则A hapen-before C.

    public class VolatileExample extends Thread {
    
    
        //设置类静态变量,各线程访问这同一共享变量
        private static boolean flag = false;
    
        public static void main(String[] args) throws Exception {
            new VolatileExample().start();
            //sleep的目的是等待线程启动完毕,也就是说进入run的无限循环体了
            Thread.sleep(100);
            flag = true;
        }
    
        //无限循环,等待flag变为true时才跳出循环
        public void run() {
            while (!flag) {
    
            }
            ;
        }
    
    
    }

    把变量加上 volatile 可以验证这个关键字的可见性!

    二、防止重排序,指令重排遵守 as-if -seril

    典型问题dcl 双重锁问题,具体问题不在阐述

     

    这个例子比较好,测试出了重排序的效果

    public class SimpleHappenBefore {
        /** 这是一个验证结果的变量 */
        private static int a=0;
        /** 这是一个标志位 */
        private static boolean flag=false;
     
        public static void main(String[] args) throws InterruptedException {
            //由于多线程情况下未必会试出重排序的结论,所以多试一些次
            for(int i=0;i<1000;i++){
                ThreadA threadA=new ThreadA();
                ThreadB threadB=new ThreadB();
                threadA.start();
                threadB.start();
     
                //这里等待线程结束后,重置共享变量,以使验证结果的工作变得简单些.
                threadA.join();
                threadB.join();
                a=0;
                flag=false;
            }
        }
     
        static class ThreadA extends Thread{
            public void run(){
                a=1;
                flag=true;
            }
        }
     
        static class ThreadB extends Thread{
            public void run(){
                if(flag){
                    a=a*1;
                }
                if(a==0){
                    System.out.println("ha,a==0");
                }
            }
        }
    }
  • 相关阅读:
    采用坐标变换(移动和旋转)画箭头
    学会Func
    一个链接器的实现
    linux内核skb操作
    终于实现samba可写不可删除
    删掉SafeDrv病毒(这个病毒有点意思)
    Writing a ServiceMain Function(使用RegisterServiceCtrlHandler函数)
    利用Winscp,Putty实现Windows下编写Linux程序
    联发科6亿美元将大陆子公司卖给四维图新(180个人价值6亿美元)
    TFTP:简单文本传输协议,BOOTP:引导程序协议
  • 原文地址:https://www.cnblogs.com/jinjian91/p/8728675.html
Copyright © 2011-2022 走看看