zoukankan      html  css  js  c++  java
  • 指令重排序

    在多线程并发编程的过程中,执行重排序有时候会造成错误的后果,比如一个线程在main线程中调用setFlag(true)的前边修改了某些程序配置项,而在t1线程里需要用到这些配置项,所以会造成配置缺失的错误。但是java给我们提供了一些抑制指令重排序的方式。

    1.同步代码抑制指令重排序

    将需要抑制指令重排序的代码放入同步代码块中:

    在获取锁的时候,它前边的操作必须已经执行完成,不能和同步代码块重排序;在释放锁的时候,同步代码块中的代码必须全部执行完成,不能和同步代码块后边的代码重排序。

    2.volatile变量抑制指令重排序

    public class Reordering {
    
        private static volatile boolean flag;
        private static int num;
    
        public static void main(String[] args) {
            Thread t1 = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while (!flag) {
                        Thread.yield();
                    }
    
                    System.out.println(num);
                }
            });
            t1.start();
            num = 5;
            flag = true;
        }
    }
    

      

    具体抑制重排序的规则如下:

    1. volatile写之前的操作不会被重排序到volatile写之后。

    2. volatile读之后的操作不会被重排序到volatile读之前。

    3. 前边是volatile写,后边是volatile读,这两个操作不能重排序。

    3.final变量抑制指令重排序

    具体的规则就这两条:

    1. 在构造方法内对一个final字段的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。

    2. 初次读一个包含final字段对象的引用,与随后初次读这个final字段,这两个操作不能重排序。

  • 相关阅读:
    POI_Excel表格数据导入导出实例--支持xls/xlsx格式
    js图片压缩工具---base64码上传插件,兼容h5和微信端(lrz.mobile.min.js)
    同一个页面,加载不同版本jQuery
    This method isn't transactional
    jquery.cookie的使用,记住用户名
    正则表达式 2017/6/12
    kSet 2017/6/6
    差分与二维差分
    求组合数
    高精度
  • 原文地址:https://www.cnblogs.com/hongchengshise/p/10409941.html
Copyright © 2011-2022 走看看