zoukankan      html  css  js  c++  java
  • 单例模式

    public class DoubleLock{

    //如果此处不加volatile,当线程A执行到"  doubleLock = new DoubleLock(); "这一行,而线程B执行到外层的"if (singleton == null) "时,可能出现instance还未完成构造,

    //但是此时不为null导致线程B获取到一个不完整的instance。

    //之所以会出现这种情况,是因为JVM的指令重排序。

        private static volatile DoubleLock doubleLock = null;//volatile防止指令重排序(很重要,不加会造成拿到初始化不完全的实例),内存可见(缓存中的变化及时刷到主存,并且其他的内存失效,必须从主存获取)

        private DoubleLock(){

            //构造器必须私有  不然直接new就可以创建

        }

        public static DoubleLock getInstance(){

            //第一次判断,假设会有好多线程,如果doubleLock没有被实例化,那么就会到下一步获取锁,只有一个能获取到,

            //如果已经实例化,那么直接返回了,减少除了初始化时之外的所有锁获取等待过程

            if(doubleLock == null){

                synchronized (DoubleLock.class){ //这个DoubleLock是public class Singleton这个类名

                    //第二次判断是因为假设有两个线程A、B,两个同时通过了第一个if,然后A获取了锁,进入然后判断doubleLock是null,他就实例化了doubleLock,然后他出了锁,

                    //这时候线程B经过等待A释放的锁,B获取锁了,如果没有第二个判断,那么他还是会去new DoubleLock(),再创建一个实例,所以为了防止这种情况,需要第二次判断

                    if(doubleLock == null){

                        //下面这句代码其实分为三步:

                        //1.开辟内存分配给这个对象

                        //2.初始化对象

                        //3.将内存地址赋给虚拟机栈内存中的doubleLock变量

                        //注意上面这三步,第2步和第3步的顺序是随机的,这是计算机指令重排序的问题

                        //假设有两个线程,其中一个线程执行下面这行代码,如果第三步先执行了,就会把没有初始化的内存赋值给doubleLock

                        //然后恰好这时候有另一个线程执行了第一个判断if(doubleLock == null),然后就会发现doubleLock指向了一个内存地址

                        //这另一个线程就直接返回了这个没有初始化的内存,所以要防止第2步和第3步重排序 所以在开头加了volatile

                        doubleLock = new DoubleLock();

                    }

                }

            }

            return doubleLock;

        }

    }

  • 相关阅读:
    5.19 省选模拟赛 T1 小B的棋盘 双指针 性质
    5.15 省选模拟赛 容斥 生成函数 dp
    5.15 省选模拟赛 T1 点分治 FFT
    5.15 牛客挑战赛40 B 小V的序列 关于随机均摊分析 二进制
    luogu P4929 【模板】舞蹈链 DLX
    CF 878E Numbers on the blackboard 并查集 离线 贪心
    5.10 省选模拟赛 拍卖 博弈 dp
    5.12 省选模拟赛 T2 贪心 dp 搜索 差分
    5.10 省选模拟赛 tree 树形dp 逆元
    luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
  • 原文地址:https://www.cnblogs.com/wl889490/p/12639412.html
Copyright © 2011-2022 走看看