设计模式(创建型模式-单例模式)

定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类
 
单例模式的特点:
  1. 单例类只可有一个实例(不能通过new来创建对象)
  2. 单例类必须自已创建自已这唯一的实例
  3. 单例类必须给所有其它对象提供这一实例
 
单例模式的适用条件:
  1. 在一个系统要求一个类只有一个实例时,才应当使用单例模式。反过来说,如果一个类可以有几个实例共存,那么就没有必要使用单例类.
  2. 类中没有属性,只有方法

 

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中的单例模式中为了提高性能,使用了双重加锁机制。

 

posted @ 2018-08-25 18:07  cao_xiaobo  阅读(371)  评论(0编辑  收藏  举报