单例模式
单例类(Singleton)
实现单例模式关键点:
- 构造函数私有
- 通过一个静态方法或枚举返回单例类对象
- 确保单例类的对象有且仅有一个,特别在多线程环境下
- 确保单例类对象在反序列化时不会重新构建对象 [ 1-4 方式都会在被反序列化时重新生成对象,必须加上如下方法:] 但枚举方法不存在这种问题。
private Object readResolve() throws ObjectStreamException{
return sInstance; //返回现有对象,而不是默认重新生成
}
单例模式的实现方式:
1、饿汉式:在声明静态对象时就初始化
public class Singleton{
private static final Singleton mSingleton = new Singleton();
private Singleton(){
}
public static Singleton getSingleton(){
return mSingleton;}
}
2、懒汉式:在第一次调用 getSingleton() 进行初始化
优点:单例只有在使用的时候才被实例化,在一定程度上节约资源。
缺点:第一次加载需要及时进行实例化,反应稍慢,最大的问题是每次调用 getSingleton() 都进行同步,造成不必要的同步开销。不建议使用。
public class Singleton{
private static Singleton mSingleton;
private Singleton(){
}
public static synchronized Singleton getSingleton(){
if(mSingleton == null){
mSingleton = new Singleton();
}
return mSingleton;
}
}
3、 Double Check Lock (DCL):(使用最多)
优点:既能在需要时才初始化,又能保证线程安全,且单例对象初始化后不再进行同步锁。效率高,资源利用率高。
缺点:第一次加载反应稍慢,由于 java 的内存模型的原因偶尔失败。在高并发下有一定的缺陷,但发生概率极小。
public class Singleton{
private static Singleton mSingleton = null;
private Singleton(){
}
public static Singleton getSingleton(){
if(mSingleton == null){
//避免不必要的同步
synchronized(Singleton.class){
if(mSingleton == null){
mSingleton = new Singleton();
}
}
}
return mSingleton;
}
}
4、静态内部类单例模式:调用 getSingleton() 时初始化。第一次调用 getSingleton() 方法会导致虚拟机加载 SingletonHolder 类,确保线程安全,保证单例对象的唯一性,延迟了单例的实例化。推荐使用
public class Singleton{
private Singleton(){
}
public static Singleton getSingleton(){
return SingletonHolder.sInstance;
}
//静态内部类
private static class SingletonHolder{
private static final Singleton sInstance = new Singleton();
}
}
5、枚举
public enum SingletonEnum{
INSTANCE;
public void doSomething{
System.out.printlin("do sth.")
}
}
6、使用容器实现单例模式:建立统一的管理类,利用键区分。管理多种类型的单例。减低使用成本,隐藏具体实现,降低耦合度。
public class SingletonManager{
private static Map<String,Object> objMap = new HashMap<>();
private SingletonManager(){
}
public static void registerService(String key, Object instance){
if(!objMap.contains(key)){
objMap.put(key,instance);
}
}
public static Object getService(String key){
return objMap.get(key);
}
}
文章评论