设计模式一:单例模式

1、单例模式的实现方式


/**
 * 1、饿汉模式
 */
public class Singleton1 {
    private static AtomicInteger count = new AtomicInteger(0);
    private static final Singleton1 instance = new Singleton1();

    public static Singleton1 getInstance(){
        return instance;
    }
}
/**
 * 2、懒汉模式
 */
public class Singleton2 {
    private static AtomicInteger count = new AtomicInteger(0);
    private static Singleton2 instance = null;
    
    private Singleton2(){}
    public static Singleton2 getInstance(){
        if(instance == null){
            count.incrementAndGet();
            instance = new Singleton2();
        }
        return instance;
    }
    public static int getCount(){
        return count.get();
    }
}
/**
 * 3、不安全的锁
 */
public class Singleton3 {
    private static AtomicInteger count = new AtomicInteger(0);
    private static Singleton3 instance = null;

    public static Singleton3 getInstance(){
        if(instance == null){
            synchronized (Singleton3.class){
                count.incrementAndGet();
                instance = new Singleton3();
            }
        }
        return instance;
    }
    private Singleton3(){}
    public static int getCount(){
        return count.get();
    }
}
/**
 * 4、不安全的锁 volatile
 */
public class Singleton4 {
    private static AtomicInteger count = new AtomicInteger(0);
    private static volatile Singleton4 instance = null;

    public static Singleton4 getInstance(){
        if(instance == null){
            count.incrementAndGet();
            instance = new Singleton4();
        }
        return instance;
    }
    private Singleton4(){}
    public static int getCount(){
        return count.get();
    }
}
/**
 * 5、双重校验锁
 */
public class Singleton5 {
    private static AtomicInteger count = new AtomicInteger(0);
    private static Singleton5 instance = null;

    public static Singleton5 getInstance(){
        if(instance == null){
            synchronized (Singleton5.class){
                if(instance == null){
                    count.incrementAndGet();
                    instance = new Singleton5();
                }
            }
        }
        return instance;
    }
    private Singleton5(){}
    public static int getCount(){
        return count.get();
    }
}
/**
 * 6、spring静态工厂生成单例对象,单例注册表
 */
public class Singleton6{
    private static AtomicInteger count = new AtomicInteger(0);
    private static HashMap<String, Object> registry = new HashMap<>();

    static {
        Singleton6 instance = new Singleton6();
        registry.put(instance.getClass().getName(), instance);
    }


    public static Singleton6 getInstance(String name){
        if(name == null){
            name = "com.xf.singleton.Singleton6";
        }
        if(registry.get(name) == null){
            try {
                count.incrementAndGet();
                registry.put(name, Class.forName(name).newInstance());
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        }
        return (Singleton6) registry.get(name);
    }

    public static int getCount(){
        return count.get();
    }
}

2、spring中的单例实现方式

/**
*  使用了单例注册列表
*/
public abstract class AbstractBeanFactory implements ConfigurableBeanFactory {
   /**
    * 充当了Bean实例的缓存,实现方式和单例注册表相同
    */
   private final Map singletonCache = new HashMap();
   public Object getBean(String name)throws BeansException {
      return getBean(name, null, null);
   }
   // ...
   public Object getBean(String name, Class requiredType, Object[] args)throws BeansException {
      //对传入的Bean name稍做处理,防止传入的Bean name名有非法字符(或则做转码)
      String beanName = transformedBeanName(name);
      Object bean = null;
      //手工检测单例注册表
      Object sharedInstance = null;
      //使用了代码锁定同步块,原理和同步方法相似,但是这种写法效率更高
      synchronized (this.singletonCache) {
         sharedInstance = this.singletonCache.get(beanName);
      }
      if (sharedInstance != null) {
         // ...
         //返回合适的缓存Bean实例
         bean = getObjectForSharedInstance(name, sharedInstance);
      } else {
         // ...
         //取得Bean的定义
         RootBeanDefinition Invalid timestamp = getMergedBeanDefinition(beanName, false);
         // ...
         //根据Bean定义判断,此判断依据通常来自于组件配置文件的单例属性开关
         //
         //如果是单例,做如下处理
         if (mergedBeanDefinition.isSingleton()) {
            synchronized (this.singletonCache) {
               //再次检测单例注册表
               sharedInstance = this.singletonCache.get(beanName);
               if (sharedInstance == null) {
                  // ...
                  try {
                     //真正创建Bean实例
                     sharedInstance = createBean(beanName, mergedBeanDefinition, args);
                     //向单例注册表注册Bean实例
                     addSingleton(beanName, sharedInstance);
                  } catch (Exception ex) {
                     // ...
                  } finally {
                     // ...
                  }
               }
            }
            bean = getObjectForSharedInstance(name, sharedInstance);
         }
         //如果是非单例,即prototpye,每次都要新创建一个Bean实例
         //
         else {
            bean = createBean(beanName, mergedBeanDefinition, args);
         }
      }
      // ...
      return bean;
   }
}

spring中的单例不是线程安全的,当涉及到共享数据时需要记性多线程安全性的处理

你可能感兴趣的:(单例模式,设计模式,java)