设计模式一:单例模式

1、单例模式的实现方式


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

    public static Singleton1 getInstance(){
        return instance;
    }
}
java 复制代码
/**
 * 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();
    }
}
java 复制代码
/**
 * 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();
    }
}
java 复制代码
/**
 * 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();
    }
}
java 复制代码
/**
 * 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();
    }
}
java 复制代码
/**
 * 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中的单例实现方式

java 复制代码
/**
*  使用了单例注册列表
*/
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中的单例不是线程安全的,当涉及到共享数据时需要记性多线程安全性的处理

相关推荐
pan_junbiao26 分钟前
Spring框架的设计模式
java·spring·设计模式
远方160926 分钟前
0x-2-Oracle Linux 9上安装JDK配置环境变量
java·linux·oracle
北执南念32 分钟前
CompletableFuture+线程池使用案列
java
黄交大彭于晏1 小时前
发送文件脚本源码版本
java·linux·windows
钮钴禄·爱因斯晨1 小时前
Java 面向对象进阶之多态:从概念到实践的深度解析
java·开发语言·数据结构
鸽子炖汤1 小时前
Java中==和equals的区别
java·开发语言·jvm
hstar95272 小时前
二、即时通讯系统设计经验
java·架构
风象南2 小时前
SpringBoot的4种死信队列处理方式
java·spring boot·后端
互联网全栈架构3 小时前
遨游Spring AI:第一盘菜Hello World
java·人工智能·后端·spring
优秀的颜4 小时前
计算机基础知识(第五篇)
java·开发语言·分布式