• 设计模式之单例模式实践


    概念

      单例模式即一个JVM内存中只存在一个类的对象实例

    分类

      1、懒汉式

       类加载的时候就创建实例

      2、饿汉式

      使用的时候才创建实例

      当然还有其他的生成单例的方式,双重校验锁,枚举和静态内部类,文中会有介绍

    实践

      懒汉式

      1)线程不安全,不可用

     1 public class Singleton {  
     2 
     3     private static Singleton instance;  
     4 
     5     private Singleton (){}  
     6 
     7   
     8 
     9     public static Singleton getInstance() {  
    10 
    11     if (instance == null) {  
    12 
    13         instance = new Singleton();  
    14 
    15     }  
    16 
    17     return instance;  
    18 
    19     }  
    20 
    21 } 

      2)线程安全,同步方法,效率低,不推荐

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

      3)线程不安全,会产生多个实例,不可用

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

    饿汉式无线程安全问题,不能延迟加载,影响系统性能

      4)

    public class Singleton {  
    
        private static Singleton instance = new Singleton();  
    
        private Singleton (){}  
    
        public static Singleton getInstance() {  
    
      return instance;  
    
        }  
    
    } 

      5)

    public class Singleton {  
    
        private static Singleton instance = null;  
    
        static {  
    
        instance = new Singleton();  
    
        }  
    
        private Singleton (){}  
    
        public static Singleton getInstance() {  
    
      return instance;  
    
        }  
    
    }

    6)双重校验锁,线程安全,推荐使用

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

    7)静态内部类,线程安全,主动调用时才实例化,延迟加载效率高,推荐使用

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

    8)枚举类型,无线程安全问题,避免反序列化创建新的实例,很少使用

    public enum Singleton {  
    
        INSTANCE;  
    
        public void whateverMethod() {  
    
        }  
    
    }

    注意事项

      1、考虑多线程问题

      2、单例类构造方法要设置为private类型禁止外界new创建

        private Singleton() {}

      3、如果类可序列化,考虑反序列化生成多个实例问题,解决方案如下

    private Object readResolve() throws ObjectStreamException {  
    
    // instead of the object we're on, return the class variable INSTANCE  
    
    return INSTANCE;  
    
    }  

    使用场景

      1、工具类对象

      2、系统中只能存在一个实例的类

      3、创建频繁或又耗时耗资源且又经常用到的对象

      另外,spring容器中的实例默认是单例饿汉式类型的,即容器启动时就实例化bean到容器中,当然也可以设置懒汉式defalut-lazy-init="true"为延迟实例化,用到时再实例化。

  • 相关阅读:
    LOJ-10108(欧拉回路+并查集)一个图至少用几笔画成
    hdu-1878(欧拉回路)
    LOJ-10106(有向图欧拉回路的判断)
    欧拉回路
    LOJ-10105(欧拉回路模板,套圈法,递归)
    LOJ-10102(求A到B之间的割点)
    LOJ-10103(求删去割点后最多的连通分量)
    LOJ-10102(桥的判断)
    【XSY2278】【HDU5669】the Red Sun(线段树+dijkstra)
    【XSY2434】【CF787D】遗产(线段树+dijkstra)
  • 原文地址:https://www.cnblogs.com/itworkerlittlewrite/p/10703840.html
Copyright © 2020-2023  润新知