单例模式解析

1、饿汉模式
优点:在类初始化时已经实例化完成,调用时较快;线程安全
缺点:不管后期是否使用,都进行了一次初始化,有可能浪费资源

public class SingleTon{

     private static final SingleTon mInstane=new SingleTon();
     private SingleTon(){} //构造函数私有化

     public static SingleTon getInstance(){
          return mInstance;
     }
}

2、懒汉模式(不推荐)
优点:只有在第一次使用时才会被初始化,一定程度上节约了资源
缺点:第一次加载时需要及时进行实例化,反应稍慢; 每次调用getInstance都进行同步,造成不必要的开销

public class SingleTon{
     private SingleTon(){} //构造函数私有化
     private static SingleTon mInstane=null;

     public static synchronized SingleTon getInstance(){
         if(mInstance == null){
              mInstance=new SingleTon();
          }
         return mInstance;
     }
}

3、DCL(Double CheckLock)
优点:第一次使用时才被初始化,节约资源; 线程安全; 第一次判null主要是为避免了不必要的同步
缺点:第一次加载时需要及时进行实例化,反应稍慢; 极低概率DCL失效,难以定位问题(jdk 1.5之后,mInstance添加volatile关键字可解决此问题)
PS: DCL失效问题可参考http://blog.itpub.net/28912557/viewspace-762047/

public class Singleton{
     private static Singleton mInstance=null;
     private Singleton(){} //构造函数私有化

     public static Singleton getInstance(){
         if(mInstance==null){
              synchronized (Singleton.class){
                   if(mInstance==null){
                        mInstance=new Singleton(); 
                    } 
               } 
          }
          return mInstance; 
     }
}

4、静态内部类(推荐)
优点:第一次使用时才被初始化; 线程安全; 保证单例对象唯一性; 比优化过的DCL更“优雅”
缺点:第一次加载时需要及时进行实例化,反应稍慢

public class Singleton{
     private Singleton(){}  //构造函数私有化
     public static Singleton getInstance(){
          return SingletonHolder.mInstance;
     }

     private static class SingletonHolder{
          private static final Singleton mInstance=new Singleton();      
     }
}            

5、枚举单例(推荐)
优点:写法简洁; 枚举实例的创建是线程安全的; 并且在任何情况下它都是一个单例,其他几种方式在反序列化时会重新生成对象,要想防止反序列化,就要加入额外的代码( private Object readResolve() throws ObjectStreamException{return mInstance} )

public enum SingleTon{
     INSTANCE;
     public void doSomething(){

     }
}

6、使用容器实现单例模式(有兴趣可以深入了解)

public class SingletonManager{
     private static Map<String, Object> objMap=new HashMap<String, Object>();

     private Singleton(){}
     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); 
     }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值