结构
单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。

代码如下:
public class Singleton {
private static Singleton instance;
private Singleton(){
}
public static Singleton GetInstance(){
if (instance==null){
instance=new Singleton();
}
return instance;
}
}
优缺点
- 优点:保证一个对象只有一个实例
- 缺点:不能解决删除单个对象的问题
实现方式
饿汉式
类加载时就初始化
/**
* 饿汉式单例
*/
public class Hungry {
private Hungry(){
}
private final static Hungry hungry = new Hungry();
public static Hungry getInstance(){
return hungry;
}
}
懒汉式
线程不安全
不支持多线程,没有加锁
public class LazyMan{
private static LazyMan instance;
private LazyMan (){}
public static LazyMan getInstance() {
if (instance == null) {
instance = new LazyMan();
}
return instance;
}
}
线程安全
第一次调用才初始化,避免内存浪费
//懒汉式单例模式
public class LazyMan{
private static LazyMan instance;
private LazyMan (){}
public static synchronized LazyMan getInstance() {
if (instance == null) {
instance = new LazyMan();
}
return instance;
}
}
双重加锁DCL
安全且在多线程情况下保持高性能。
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
静态内部类
类的静态属性只会在第一次加载类的时候初始化,JVM帮助我们保证了线程的安全性。
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
枚举
不仅避免多线程同步问题,还能防止反序列化重复创建对象。
public enum EnumSingle {
INSTANCE;
public EnumSingle getInstance(){
return INSTANCE;
}
}
应用场景
spring依赖注入bean默认是单例的
/**
* Return the (raw) singleton object registered under the given name.
* <p>Checks already instantiated singletons and also allows for an early
* reference to a currently created singleton (resolving a circular reference).
* @param beanName the name of the bean to look for
* @param allowEarlyReference whether early references should be created or not
* @return the registered singleton object, or {@code null} if none found
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
从源码可以看出,使用了双重加锁DCL的单例模式。可以避免bean实例被重复创建。
这里使用singletonFactory.getObject()返回具体beanName对应的ObjectFactory来创建bean。
参考文章:
菜鸟联盟-单例模式
Java单例模式详解:实现方式与应用场景
339

被折叠的 条评论
为什么被折叠?



