设计模式(创建型模式-单例模式)
定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类
单例模式的特点:
- 单例类只可有一个实例(不能通过new来创建对象)
- 单例类必须自已创建自已这唯一的实例
- 单例类必须给所有其它对象提供这一实例
单例模式的适用条件:
- 在一个系统要求一个类只有一个实例时,才应当使用单例模式。反过来说,如果一个类可以有几个实例共存,那么就没有必要使用单例类.
- 类中没有属性,只有方法
1.饿汉式单例
public class Singleton { private static final Singleton uniqueInstance = new Singleton(); //私有-不能通过new来创建对象 private Singleton(){ } public static Singleton getInstance() { return uniqueInstance; } }
优点:不需要使用synchronized就能保证线程安全
缺点:类加载的时候就会new一个静态对象,当系统使用这样的类较多时,会使得启动速度变慢,这种适合小系统。现在流行的设计都讲得是“延迟加载”,我们可以在第一次使用的时候才初始化第一个该类的对象,当不需要使用的时候就无需创建出一个对象。
2.懒汉式单例
public class Singleton { private static Singleton uniqueInstance = null; // 私有-不能通过new来创建对象 private Singleton() { } // 线性安全的 public synchronized static Singleton getInstance() { if(uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } }
3.内部类单例
public class Singleton { //私有-不能通过new来创建对象 private Singleton(){ } private static class Inner { private static Singleton s = new Singleton(); } public static Singleton getInstance() { return Inner.s; } }
优点:延迟加载
spring bean 中的单例模式
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { /** * Return the (raw) singleton object registered under the given name. * <p>Checks already instantiated singletons and also allows for an early * reference to a currently created singleton (resolving a circular reference). * @param beanName the name of the bean to look for * @param allowEarlyReference whether early references should be created or not * @return the registered singleton object, or {@code null} if none found */ protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return (singletonObject != NULL_OBJECT ? singletonObject : null); } }
在源码中可以看出,spring中的单例模式中为了提高性能,使用了双重加锁机制。