一些收藏Java

【并发编程】- 内存模型(针对JSR-133内存模型)篇

2021-01-06  本文已影响0人  双木ll之林

并发编程模型

总结:Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式进行,整个通信过程对程序员完全透明。


附图:


image

注:所有实例域、静态域和数组元素都存储在堆内存中,堆内存在线程之间共享(本章用“共享变量”这个术语代指实例域,静态域和数组元素)。局部变量(Local Variables),方法定义参数(Java语法规范称之为Formal Method Parameters)和异常处理器参数(Exception HandlerParameters)不会在线程之间共享,它们不会有内存可⻅性问题,也不受内存模型的影响。




image

现代处理器采用了指令级并行技术(Instruction-Level Parallelism,ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序
内存系统的重排序
由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行



    public class DoubleCheckedLocking { // 1
        private static Instance instance; // 2

        public static Instance getInstance() { // 3
            if (instance == null) { // 4:第一次检查
                synchronized (DoubleCheckedLocking.class) { // 5:加锁
                    if (instance == null) // 6:第二次检查
                        instance = new Instance(); // 7:问题的根源出在这里
                } // 8
            } // 9
            return instance; // 10
        } // 11
    }
    memory = allocate();  //1:分配对象的内存空间
    ctorInstance(memory);  //2:初始化对象
    instance = memory;   //3:设置instance指向刚分配的内存地址
    memory = allocate();  //1:分配对象的内存空间
    instance = memory;   //3:设置instance指向刚分配的内存地址
                          //注意,此时对象还没有被初始化!
    ctorInstance(memory); //2:初始化对象
    public class SafeDoubleCheckedLocking {
        private volatile static Instance instance;

        public static Instance getInstance() {
            if (instance == null) {
                synchronized (SafeDoubleCheckedLocking.class) {
                    if (instance == null)
                        instance = new Instance(); // instance为volatile,现在没问题了
                }
            }
            return instance;
        }
    }
    public class InstanceFactory {
        private static class InstanceHolder {
            public static Instance instance = new Instance();
        }

        public static Instance getInstance() {
            return InstanceHolder.instance;  // 这里将导致InstanceHolder类被初始化,存在初始化锁,拿不到的线程会一直等待
        }
    }

happens-before是JMM最核心的概念

1) 关系的定义

2) 规则

注意:两个操作之间具有happens-before关系,并不意味着前
一个操作必须要在后一个操作之前执行!happens-before仅仅要求前一个操
作(执行的结果)对后一个操作可见,且前一个操作按顺序排在第一个操
作之前(the first is visible to and ordered before the second)。

话外语:

  • as-if-serial语义保证单线程内程序的执行结果不被改变,happens-before关系保证正确同步的多线程程序的执行结果不被改变
  • as-if-serial语义和happens-before这么做的目的,都是为了在不改变程序执行结果的前提下,尽可能地提高程序执行的并行度

上一篇 下一篇

猜你喜欢

热点阅读