• java单例模式总结


    常见安全的单例实现代码和自己的一点理解。

    一、 饿汉模式(静态初始化)

    class Singleton{
        
        private Singleton(){
        }
        
        private static Singleton cache=new Singleton();
        
        public static Singleton getInstance(){
            return Internal.cache;
        }
    }
    
    

    实现最为简单,但是如果Singleton的任何一个静态字段(非常量,常量是被动引用,在编译时通过常量传播优化,放入常量池,转化为了对常量池的引用)或者静态方法被调用则会初始化。线程安全有虚拟机的保证,对象的实例化是在类加载的初始化阶段。初始化的时机详见:深入理解java虚拟机p210

    二、双重检查锁(dcl)

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

    双重检查锁是为了解决资源初始化较慢或者资源较重的场景下延迟初始化,利用synchronized关键字保证线程安全。饿汉模式是利用虚拟机本身保证类加载的的线程安全性。但是dcl本身每次都需要检查该对象是否实例化,所以引出下面的模式

    三、 延迟占位类

    class Singleton{
        
        private Singleton(){
        }
        
        private static final class Internal{
            static Singleton cache=new Singleton();
        }
        
        public static Singleton getInstance(){
            return Internal.cache;
        }
    }
    
    

    延迟占位类结合前两种的优势,消除了同步并且实现了延迟初始化。延迟占位类模式的线程安全也是由虚拟机来保证的,这里需要理解的是为什么能延迟初始化。相比于饿汉模式,延迟占位类模式可以实现调用getInstance方法才去初始化该类

    四、枚举实现

    effective java中的推荐做法。我找了一个jdk中的实现如下:

       enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
            INSTANCE;
    
            @Override
            public int compare(Comparable<Object> c1, Comparable<Object> c2) {
                return c1.compareTo(c2);
            }
    
            @Override
            public Comparator<Comparable<Object>> reversed() {
                return Comparator.reverseOrder();
            }
        }
    
    

    枚举本身更加安全,虚拟机层面阻止了通过反射去实例化一个类导致单例破坏的场景。

    最后

    此外还有懒汉模式(线程不安全)和懒汉模式直接加synchronized(性能问题)的,这种代码比较简单,实际也没使用的意义就不展开了。

  • 相关阅读:
    【转】K/3 KIS BOS 插件入门
    [转]SQL Server 存储过程中使用 in 动态变量
    [转]Delphi 12种大小写转换的方法
    cxGrid FilterRow 添加左模糊查询,实现 %ABC%
    cxGrid 锁定一行,让该行数据不能编辑
    K/3工业单据K3BillTransfer的属性及使用方法
    VB6上创建金蝶K/3或KIS旗舰版插件
    MySQL UTF8 中文乱码处理
    两种方法自动部署代码:webhooks钩子自动部署代码方法一 及定时任务自动部署二 简介
    Linux查看进程的4种方法
  • 原文地址:https://www.cnblogs.com/chenfangzhi/p/10387644.html
Copyright © 2020-2023  润新知