DesignPattern-创建型-Singleton
1、简介
单例模式下,一个类只能有一个实例。外部能获取到的实例都是一样的。
Spring中的Bean默认就是单例的。
单例减少了内存占用。
如何实现?
唯一实例:static。
外部不能再创建对象:将构造器声名为私有的。
外部获取单例对象:声名一个工厂方法返回单例引用。
2、实现
/** * 线程不安全 * 延迟初始化 */ class Singleton1{ private Singleton1(){} private static Singleton1 singleton1; public static Singleton1 getInstance(){ if(singleton1==null) singleton1=new Singleton1(); return singleton1; } } /** * Singleton1的改进 * 用锁保证线程安全 * 延迟初始化 * 由于锁住了整个方法,效率较低 */ class Singleton3{ private Singleton3(){} private static Singleton3 singleton3; public static synchronized Singleton3 getInstance(){ if(singleton3==null) singleton3=new Singleton3(); return singleton3; } } /** * 利用了虚拟机类加载的机制,在类加载时就完成了实例创建 * 安全发布,线程安全 */ class Singleton2{ private Singleton2(){} private static final Singleton2 singleton2=new Singleton2(); public static Singleton2 getInstance(){ return singleton2; } } /** * 相较于锁住整个方法,减小了同步代码块的大小 * 并且,只有在进行实例创建时才进行同步 * 同时,为了防止运行时的指令重排序,将singleton4声名为volatile * 安全发布,线程安全 * 延迟初始化 */ class Singleton4{ private Singleton4(){} private static volatile Singleton4 singleton4; public static Singleton4 getInstance(){ if(singleton4==null){ synchronized (Singleton4.class){ if (singleton4==null) singleton4=new Singleton4(); } } return singleton4; } } /** * 使用了静态内部类来持有单例 * 在静态内部类加载时完成了实例创建,是安全的发布 * 只用在访问静态内部类的静态域时,才会发生静态内部类的加载和单例的创建,因此是延迟初始化的 */ class Singleton5{ private Singleton5(){} private static class InnerHolder{ private static Singleton5 singleton5=new Singleton5(); } public static Singleton5 getInstance(){ return InnerHolder.singleton5; } }

浙公网安备 33010602011771号