《单例模式》

单例模式

  • 单例模式
    • 1.非线程安全懒汉式
    • 2.线程安全懒汉式
    • 3.饿汉式(线程安全)
    • 4.双重校验锁(DCL,即 double-checked locking,线程安全的)
    • 5.静态内部类(线程安全)
    • 6.枚举(线程安全):首选单例模式

单例模式

  • 特点:
    • 1.单例类只能有一个实例。
    • 2.单例类必须自己创建自己的唯一实例。
    • 3.对外提供一种访问其唯一对象的方式。
  • 意图:保证一个类仅有一个实例,并提供一个全局访问点。
  • 主要解决:一个全局使用的类,频繁的创建和销毁。(例:一个班级只有一个班主任)

1.非线程安全懒汉式

  • 是否延迟初始化:是
public class Singleton{
    private static Singleton instance;
    private Singleton(){}//私有化的构造函数
    //对外提供方法获取唯一实例
    public static Singleton getInstance(){
     if(instance==null){
        instance = new Singleton();   
     }
     return instance;
    }    
}

2.线程安全懒汉式

  • 是否延迟初始化:是
  • 优点:第一次调用才初始化,避免内存浪费。
  • 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
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 instance = new Singleton();
    private Singleton(){};
    public static Singleton getInstance(){
      return instance;
    }

}

4.双重校验锁(DCL,即 double-checked locking,线程安全的)

  • 是否 延迟初始化:是
  • 在双重检查锁中,代码会检查两次单例类是否有已存在的实例,一次不加锁检测和一次加锁检测
  • 第一层校验的意义在于防止不必要的加锁,浪费性能,第二层校验,保证对象的单例。
public class Singleton {  
    //volatile 关键字保证该对象在多线程环境下的可见性
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  //第一层校验
        synchronized (Singleton.class) {  
        if (singleton == null) {  //第二层检验
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}

5.静态内部类(线程安全)

  • 是否延迟初始化:是
public class Singleton{
     private static class SingletonHolder{
       private static final Singleton INSTANCE = new Singleton();     
     }
     private Singleton(){}
     public static final Singleton getInstance(){
        return SingletonHolder.INSTANCE;
     }
}

6.枚举(线程安全):首选单例模式

  • 是否延迟初始化:否
@Data
public class User{
    private Integer no ;
    private Integer age ;
    private String name ;
    //构造函数私有化,防止被外部实例化
    private User(){}
    //静态内部枚举,维护唯一实例
    static enum Single{
        SINGLE;
        private User user;
        private Single(){
            this.user = new User();
        }
    }
    //对外提供获取唯一实例方法
    public static User instance(){
        return Single.SINGLE.user;
    }
}


public class Test{
    public static void main(String[] args) {
        User instance = User.instance();
        System.out.println("instance = " + instance);
        User instance1 = User.instance();
        System.out.println("comparator = " + (instance1==instance));//true
    }
}

你可能感兴趣的:(JAVA设计模式)