zoukankan      html  css  js  c++  java
  • java内存模型

    并发编程模型的分类

    • 并发编程中遇到的两个问题: 线程之间如何通信, 线程之间如何同步
    • 以线程之间的通信模式来看, 并发模型可以分为两种
      ** 共享内存的并发模型
      ** 消息传递的并发模型
    • java并发采用的是共享内存模型

    JMM抽象模型

    • java中, 堆内存是线程之间共享的, 其中包括了实例域、静态域、数组元素, 而局部变量、
      方法参数、异常处理参数是线程私有的, 不会有内存可见性问题, 不受内存模型影响
    • JMM决定了一个线程对共享变量的写入何时对另一个线程可见
    • 从抽象角度来看, 共享变量存储在主内存中, 每个线程有一个副本, 读写在这个副本上, 最终由JMM决定与主内存的同步
      ** 线程A向主内存刷新变更, 线程B向主内存读取更新, 实现线程通信
    • java内存模型

    重排序

    • 编译器优化重排序
    • 指令级并行的重排序
    • 内存系统的重排序
    • JMM属于语言级的内存模型, 它确保了在不同编译器与不同处理器平台上, 通过禁止特定的重排序, 为程序员提供一致的内存可见性

    内存屏障

    实现cpu数据可见性, 禁止指令重排序

    java内存模型如何定义并发关键字的行为

    • synchronized
      ** 线程释放monitor, 把cpu缓存(线程本地缓存)刷新到主内存
      ** 线程获得monitor, 把cpu缓存失效, 强制从主内存获取
      ** 禁止特定的指令重排, synchronized关键字包裹的代码不可以重排序到外面
    • volatile
      ** volatile修饰的变量, 每次的变更都会刷新到主内存, 每次读取这种变量前, 也必须保证缓存无效
      ** 禁止特定的指令重排
    • final
      ** final修饰的变量, 在正确的构造对象后, 对其它线程是可见的

    happens-before

    双重检查锁定(double-check-locking)

    当我们写出一个标准的双重检查锁定单例模式时(如下), 代码仍是有问题的, 这是因为重排序的缘故,
    线程有可能拿到尚未实例化的对象的引用.
    使用volatile修饰类变量, 禁止helloSingleton = new HelloSingleton()这步的指令重排.

        private static HelloSingleton helloSingleton;
        public static HelloSingleton instance() {
            if (helloSingleton == null) {
                synchronized(SingletonFactory.class) {
                    if (helloSingleton == null) {
                        return helloSingleton = new HelloSingleton();
                    }
                }
            }
            return helloSingleton;
        }
    

    还有一种更加优雅的方式, 使用内部类实现, 内部类会在被引用时才加载, 实现了懒加载

    单例模式实现方式有好多种,但大部分都会有多线程环境下的问题;使用内部类可以避免这个问题,因为在多线程环境下,jvm对一个类的初始化会做限制,同一时间只会允许一个线程去初始化一个类,这样就从虚拟机层面避免了大部分单例实现的问题

        public static class innerHolder {
            public static HelloSingleton helloSingleton = new HelloSingleton();
        }
        public static HelloSingleton instanceV5() {
            return innerHolder.helloSingleton;
        }
    

    参考资料

    深入理解Java内存模型(一)——基础

    什么是Java内存模型

    双重检查锁定

  • 相关阅读:
    基于设备的回声消除
    Libcurl细说
    抓包分析YY音频
    合唱音效解释
    EXCEL-COUNTIF()统计符合区间上的值个数
    EXCEL-对筛选出(单独手动隐藏行还是在统计范围内)的表格数据进行统计
    Perl字符串处理函数用法集锦
    Selenium-IDE,在网页上模拟人的操作
    Perl哈希%hash
    Perl if条件判断
  • 原文地址:https://www.cnblogs.com/simple-huang/p/8620771.html
Copyright © 2011-2022 走看看