单例模式 饿汉式和懒汉式

单例模式

懒汉式

package com.avadakur.DesignMode.Singleton;

/**
 * @author ChenjieLu
 * @description 全局唯一的User
 * @date 2022/3/30 13:16
 */
public class User {
          
   

    private volatile static User user;

    // 在类外new User的时候,不让new
    private User() {
          
   
    }

    public void getInfo() {
          
   
        System.out.println("得到UserInfo");
    }

    /**
     * 此方法为懒汉式LazyMan单例模式只有在调用getInstance实例时才会调用new User()
     * 但是在多线程情况下,会有多个线程同时判断user == null 同时new 多个Instance实例,出现错误
     * 所以为了解决,可以加Synchronize关键字
     * 如下,但是每次getInstance都会进行同步操作,会导致运行速度变慢,所以在方法内部进行二次判断
     * 为什么要进行二次判断呢,是因为多个线程都判断user为null,在if语句块中等待,只有在sync中再次进行判断,才可以真正确认是否为null,
     * 双重检查锁定(Double-Check Locking)
     * 且要对实例添加 volatile 关键字,增加线程可见性
     * Synchronize public static User getInstance() {
     *         if (user == null) {
     *             user = new User();
     *         }
     *         return user;
     *    }
     * public static User getInstance() {
     *      *       if (user == null) {
     *                  Synchronize{
     *                      if (user == null) {
     *                          user = new User();
     *                      }
     *                  }
     *      *         }
     *      *         return user;
     *      *    }
     *
     ** @return
     */
    public static User getInstance() {
          
   
        if (user == null) {
          
   
            synchronized(User.class) {
          
   
                if (user == null) {
          
   
                    user = new User();
                }
            }

        }
        return user;
    }

}

饿汉式

/**
 * @author ChenjieLu
 * @description
 * @date 2022/3/30 13:38
 */
public class EagerUser {
          
   
    private static EagerUser eagerUser = new EagerUser();
    
    private EagerUser() {
          
   
    }
    
    public EagerUser getInstance() {
          
   
        return eagerUser;
    }
}

内部类 解决饿汉式和懒汉式的缺点,在创建InnerClassUser的时候不会初始化对象,在调用getInstance的时候内部类创建对象

/**
 * @author ChenjieLu
 * @description
 * @date 2022/3/30 13:43
 */
public class InnerClassUser {
          
   
    private static class HoldClass{
          
   
        private final static InnerClassUser innerClassUser = new InnerClassUser();
    }

    private InnerClassUser() {
          
   
    }

    public InnerClassUser getInstance() {
          
   
        return HoldClass.innerClassUser;
    }
}
经验分享 程序员 微信小程序 职场和发展