在java开发中,我们时常在上下文中仅仅只需要一个实例,而在我们实例化的过程中,每次都会在堆中产生新的对象,这时候我们就需要使用单例模式来控制实例化的数量。这在spring容器中十分的常用。现在三种方式实现多线程安全的单例模式
1,首先我们来看一个效率不高的线程安全的单例模式的实现方法
public class MySingleton {
//这里使用static保证堆中只有一个实例
private static MySingleton mysingleton;
//这里使用synchronized关键字来保证每次只有一个线程来实例化来检查
public synchronized MySingleton createSingleton() {
if (mysingleton == null) {
mysingleton = new MySingleton();
}else {
return mysingleton;
}
}
}
2,双重检查锁(对上面的一种改进)
//双重检查锁来实现,这样在实例已经存在的情况下就不用获取对象锁去判断,提高了效率
public class MySingletonA {
//注意这里一定要使用volatile保证对象在实例化的过程中不会重排序
//这里就是有可能线程A还没有实例化完成导致线程B误认为mySingleton == null
private volatile static MySingleton mySingleton;
public MySingletonA createInstance() {
if (mySingleton == null) {
synchronized(MySingletonA.class) {
if (mySingleton == null) {
mySingleton = new MySingletonA();
}
}
}
return mySingleton;
}
}
3,使用内部类的方式
//这个基于内部类的方式利用了内部类延迟加载并且线程安全的特性
public class MySingletonB {
private static class InnerMySingleton {
public static MySingletonB mySingleton = new MySingletonB();
}
public MySingletonB creatSingleton() {
return InnerMySingleton.mySingleton;
}
}
3,利用枚举
public enum MySingletonC {
private MySingletonC mySingleton = null;
}