单例模式可能是大家见得最多,应用最广泛,也是最简单的设计模式了,下面讲讲单例模式的几种实现方法以及每个实现方法的优缺点。
确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多资源,或者某种类型的对象只应该有且只有一个,例如:创建一个对象需要消耗资源过多,如访问IO和数据库等资源,这时就可以考虑用单例模式:
(一)懒汉模式
懒汉模式是声明一个静态对象,并且在用户第一次调用getInstance时进行初始化,见名思义,懒汉模式就是你需要时我才创建对象,下面是懒汉模式的代码实现:
/**
* 单例模式--懒汉模式
* @author hao
*
*/
public class SingletonA {
private static SingletonA instance;
private SingletonA() {
}
public static synchronized SingletonA getInstance(){
if(instance == null){
instance = new SingletonA();
}
return instance;
}
}
懒汉模式的优点是单例只有使用时才会被实例化,一定程度上节约了资源;缺点是每次加载都需要实例化,反应稍慢,最大的问题是每次调用getInstance时都进行了同步,造成不必要的同步开销,这种模式一般是不推荐使用的。
(二)Doubel Check Lock(DCL)实现单例
/**
* 单例模式--DCL模式
* @author hao
*
*/
public class SingletonB {
private static SingletonB instance = null;
private SingletonB() {
}
public static SingletonB getInstance(){
if(instance == null){
synchronized (SingletonB.class) {
if(instance == null){
instance = new SingletonB();
}
}
}
return instance;
}
}
DCL的优点是既能在需要时才初始化单例,又能保证线程安全,资源利用率高;缺点是在高并发环境下有一定缺陷;DCL模式是使用最多的单例模式!
(三)静态内部类单例模式
/**
* 单例模式--静态内部类模式
* @author hao
*
*/
public class SingletonC {
private SingletonC(){}
public static SingletonC getInstance(){
return SingletonHolder.sInstance;
}
/**
* 静态内部类
* @author hao
*
*/
private static class SingletonHolder{
private static final SingletonC sInstance = new SingletonC();
}
}
(四)枚举单例模式
/**
* 单例模式--枚举模式
* @author hao
*
*/
public enum SingletonD {
INSTANCE;
public void doSomething(){
System.out.println("doSomething..");
}
}
(五)使用容器实现单例
/**
* 使用容器实现单例模式
* @author hao
*
*/
public class SingletonE {
private static Map objMap = new HashMap();
private SingletonE() {
}
public static void registerService(String key,Object instance){
if(!objMap.containsKey(key)){
objMap.put(key, instance);
}
}
public static Object getService(String key){
return objMap.get(key);
}
}
以上单例模式他们的核心原理都是将构造函数私有化,各自都有自己的优缺点,选择哪种方式实现取决于项目本身的需求!