设计模式一:单例模式

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定义判断,此判断依据通常来自于组件配置文件的单例属性开关
         //<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;
   }
}

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

相关推荐

  1. 设计模式(模式)

    2024-02-20 07:16:02       35 阅读
  2. 设计模式模式

    2024-02-20 07:16:02       27 阅读
  3. 系列设计模式

    2024-02-20 07:16:02       34 阅读
  4. 设计模式

    2024-02-20 07:16:02       39 阅读
  5. 设计模式

    2024-02-20 07:16:02       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-20 07:16:02       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-20 07:16:02       20 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-20 07:16:02       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-20 07:16:02       20 阅读

热门阅读

  1. 单例模式双端检测详解

    2024-02-20 07:16:02       30 阅读
  2. 【WPF】获取父控件数据

    2024-02-20 07:16:02       35 阅读
  3. WhisperFusion:具有超低延迟无缝对话功能的AI系统

    2024-02-20 07:16:02       23 阅读
  4. WPF 在控件上预留一个占位给到调用方使用

    2024-02-20 07:16:02       24 阅读
  5. WPF大杂烩

    2024-02-20 07:16:02       26 阅读
  6. OFD文件WEB前端展示-easyofd(1.0.6)

    2024-02-20 07:16:02       30 阅读
  7. 历年CSP-J(NOIP普及组)考点分析与分类汇总

    2024-02-20 07:16:02       27 阅读
  8. ADO.NET事务处理

    2024-02-20 07:16:02       32 阅读
  9. oracle和mysql语句有哪些异同点?

    2024-02-20 07:16:02       35 阅读
  10. 如何在Win11系统中使用ubuntu(WSL)终端编译 Rust 程序

    2024-02-20 07:16:02       32 阅读