当前位置:   article > 正文

设计模式一:单例模式

设计模式一:单例模式

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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
/**
 * 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();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
/**
 * 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();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
/**
 * 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();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
/**
 * 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();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
/**
 * 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();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

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定义判断,此判断依据通常来自于组件配置文件的单例属性开关
         //<bean id="date" class="java.util.Date" scope="singleton"/>
         //如果是单例,做如下处理
         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实例
         //<bean id="date" class="java.util.Date" scope="prototype"/>
         else {
            bean = createBean(beanName, mergedBeanDefinition, args);
         }
      }
      // ...
      return bean;
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/118981
推荐阅读
相关标签
  

闽ICP备14008679号