单例模式

描述

控制一个类仅能产生一个实例。

  • 懒汉式:类加载时不会生成实例,只有在调用时才会生成实例。
  • 饿汉式:类加载时便会生成实例。

类名一般为:xxxSingleton

代码实现示例

/**
 * 最优实现:饿汉式-枚举(在Spring环境下)
 */
public enum MySingletonEnum{
    INSTANCE;
    
    private MyService myService;
    
    private MySingletonEnum(){
        myService = ApplicationContextUtil.getContext().getBean(MyService.class);
    }
    
    public String answer(){
        return myService.answer();
    }
    
    //调用:MySingletonEnum.INSTANCE.answer();
}

/**
* 推荐实现:懒汉式-静态内部类
**/
public class Singleton {

    private Singleton() {
    }

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getUniqueInstance() {
        return SingletonHolder.INSTANCE;
    }
}

/**
* 饿汉式-线程安全
**/
public class Singleton {

    private static Singleton uniqueInstance = new Singleton();

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
        return uniqueInstance;
    }
}


/**
* 懒汉式-线程安全-双重校验锁
**/
public class Singleton {

    private volatile static Singleton uniqueInstance;

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}


/**
* 懒汉式-线程不安全
**/
public class Singleton {

    private static Singleton uniqueInstance;

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}



实际应用场景

FAQ

Spring Bean 实例默认是单例的吗?

单例类如果不想注册到Spring,但又需要依赖Spring Bean,应该怎么写?

Last Updated:
Contributors: dongyz8