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

    1.双重检查锁 & volatile保证可见性(变量值改动后及时从工作内存写回主内存)和有序性(指令不可重排)

    public class Singleton {
        private static volatile Singleton singleton = null;
        
        private Singleton(){}
        
        public static Singleton getSingleton(){
            if(singleton == null){
                synchronized (Singleton.class){
                    if(singleton == null){
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }    
    }

    现在我们分析一下为什么要在变量singleton之间加上volatile关键字。要理解这个问题,先要了解对象的构造过程,实例化一个对象其实可以分为三个步骤:

      (1)分配内存空间。

      (2)初始化对象。

      (3)将内存空间的地址赋值给对应的引用。

    但是由于操作系统可以对指令进行重排序,所以上面的过程也可能会变成如下过程:

      (1)分配内存空间。

      (2)将内存空间的地址赋值给对应的引用。

      (3)初始化对象

      如果是这个流程,多线程环境下就可能将一个未初始化的对象引用暴露出来,从而导致不可预料的结果。因此,为了防止这个过程的重排序,我们需要将变量设置为volatile类型的变量。

    2.利用JVM类加载的原理保证只初始化一下实例,利用内部类,保证使用时才初始化加载(满足了赖加载)

    public class Singleton {
        private static class Holder {
            private static Singleton singleton = new Singleton();
        }
        
        private Singleton(){}
            
        public static Singleton getSingleton(){
            return Holder.singleton;
        }
    }

    不管采取何种方案,请时刻牢记单例的三大要点:

    • 线程安全
    • 延迟加载
    • 序列化与反序列化安全

    https://www.cnblogs.com/andy-zhou/p/5363585.html

  • 相关阅读:
    LOJ 10160
    LOJ 10155
    2018-11-1 NOIP 模拟赛解题报告
    联考前停课集训随笔
    一个博客园代码高亮的方案
    详解使用 Tarjan 求 LCA 问题(图解)
    NOIP2018普及初赛解析
    关于CCR测评器的自定义校验器(Special Judge)
    日常,异常处理
    Androidstudio 编译慢 这样的体验肯定很多人都有!!!
  • 原文地址:https://www.cnblogs.com/genggeng/p/10013781.html
Copyright © 2011-2022 走看看