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中的单例不是线程安全的,当涉及到共享数据时需要记性多线程安全性的处理