• Java并发编程—java内存模型2


    ——————————————————————————————————

    重排序

    数据依赖性

    数据依赖不能进行重排序
    在这里插入图片描述

    as-if-serial

    • as-if-serial语义的意思是:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。
    • 【as-if-serial不允许指令重排序是要让结果不变,不是严格意义上的不允许重排序】

    重排序对多线程的影响

    class ReorderExample { 
        int a = 0; 
        boolean flag = false; 
        public void writer() { 
            a = 1; // 1 
            flag = true; // 2 
        }
        Public void reader() { 
            if (f?lag) { // 3 
            int i = a * a; // 4 
            …… 
            } 
        } 
    }
    可能出现,2->3->4->1这样的执行顺序,导致结果i=0;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    顺序一致性

    • 不让重排序
    • 顺序一致性指多线程下排队执行,只会出现写后读的情况。(看到的和执行的一样)
    • 顺序一致性内存模型有两大特性:
      • 1)一个线程中的所有操作必须按照程序的顺序来执行。
      • 2)(不管程序是否同步)所有线程都只能看到一个单一的操作执行顺序。在顺序一致性内存模型中,每个操作都必须原子执行且立刻对所有线程可见。

    同步程序的顺序一致性效果

    通过加锁实现顺序一致性,加锁后里面重排序也没有问题,因为上锁之后,切换线程后t1没有释放锁,t2无法拷贝,时间片过了之后就会切换成t1执行,t1整个方法执行完之后才会释放锁,肯定能保证t1的结果正确。

    同步/异步

    • 同步:排队;共享资源,一个一个操作资源
    • 异步:不排队;一个线程没操作完,其他线程也可以使用该资源

    总线事务

    总线事务包括读事务和写事务(事务:一系列的操作要么都成功,要么都失败-ACID)

    • 读事务从内存传送数据到处理器
    • 写事务从处理器传送数据到内存
    • 每个事务会读/写内存中一个或多个物理上连续的字
    • 关键: 总线会同步试图并发使用总线的事务

    在一个处理器执行总线事务期间,总线会禁止其他的处理器和I/O设备执行内存的读/写

    • 总线中电压会互相干扰,所以前面必须实现拦截(物理限制,导线传输电压互相有影响)
    • 如果以后变成光纤传输就不会有电压影响了,光信号支持双向传输也支持同时传输信号(例:人眼一次性能看到很多物体,不同物体光波不一样)

    当单个内存操作不具有原子性时,可能会产生意想不到后果:

    • 因为=》总线传输一个指令时,不止传输一次,会传输很多次(总线宽度是36-41位,意味着单次传输只能传输41bit数据)
    • 指令的数据传输都是基本类型数据,必须是8的倍数。(就像传long类型的数据需要分两次传输,因此传输数据都是一批次一批次的,不是单独传的,否则数据会混乱)

    双重校验锁

    双重检查锁定:人们想通过双重检查锁定来降低同步的开销。下面是使用双重检查锁定来实现延迟初始化的示例代码。
    在这里插入图片描述
    构造方法还是有问题的,还有重排序问题
    现在不锁方法了,证明方法可以被很多线程拷贝

    • 双检锁/双重校验锁(DCL,即double-checked locking)
    • JDK 版本:JDK1.5起
    • 是否Lazy初始化:是
    • 是否多线程安全:是
    • 实现难度:较复杂
    • 描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
    • getInstance()的性能对应用程序很关键。
      【实例】
    public class Singleton {  
        private volatile static Singleton singleton;  
        private Singleton (){}  
        public static Singleton getSingleton() {  
        if (singleton == null) {  
            synchronized (Singleton.class) {  
                if (singleton == null) {  
                    singleton = new Singleton();  
                }  
            }  
        }  
        return singleton;  
        }  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

  • 相关阅读:
    施努卡:3d机器视觉检测系统 3d视觉检测应用行业
    linux高级篇基础理论四(rsync,inotify,squid,KVM虚拟机)
    IDERA ER/Studio Data Architect Professional v19.3.2
    多语言网站-多语言网站更新插件-多语言网站翻译插件
    进博会期间,多地政府领导密集考察深兰科技
    在flutter中添加video_player【视频播放插件】
    【ELK使用指南 2】常用的 Logstash filter 插件详解(附应用实例)
    c语言动态内存分布
    波卡生态中“中继链”、“DOT”的常见问题解答
    论文基础常识摘录
  • 原文地址:https://blog.csdn.net/weixin_53233197/article/details/128164237