考虑性能和线程安全的java单例模式实现

yao__shun__yu转载的一篇博客详细的介绍了实现单例模式的几种方法:http://blog.csdn.net/generalfu/article/details/8142463,对性能和线程安全的阐述写得特别好。lz自己也把单例模式写了写,但不免还是会有些疏忽,本文主要是写写自己的心得和以及自己觉得还需注意的地方,对原文的第5小节也提出了一点改进,算是这篇文章的一点补充吧。


单例模式的含义为一个Singleton类只有它自身的一个实例。本文1-4小节就性能和线程安全方面易出现的问题进行了探讨,对此有兴趣的读者可以参考其中的内容。第5小节提出了较好的解决方案,想了解的读者也可以直接看这里,第5小节不以1-4小节为基础。

首先,对yao__shun__yu转载的博客中的要点概括如下:

1.饥饿模式:使用了静态工厂方法,对象设为static,在声明时便初始化了,在getSingleInstance方法中直接返回该对象,可能带来潜在的性能问题。

public final class EagerSingleton   
{   
    private static EagerSingleton singObj = new EagerSingleton();   
   
    private EagerSingleton(){   
    }   
   
    public static EagerSingleton getSingleInstance(){   
       return singObj; 
    }   
}   


2.懒汉模式:使用了延迟加载方法,对象设为static,在声明时设为null,在使用时,在getSingleInstance方法中,如果对象为null则初始化,解决了性能问题,但是是线程不安全的。

public final class LazySingleton   
{   
    private static LazySingleton singObj = null;   
   
    private LazySingleton(){   
    }   
   
    public static LazySingleton getSingleInstance(){   
        if(null == singObj ) singObj = new LazySingleton(); 
          return singObj; 
    }   
} 


3.在懒汉模式的getSingleInstance方法前加Synchronized,解决了线程安全问题,但是并发度较低。

public final class ThreadSafeSingleton   
{   
    private static ThreadSafeSingleton singObj = null;   
   
    private ThreadSafeSingleton(){   
    }   
   
    public static Synchronized ThreadSafeSingleton getSingleInstance(){   
        if(null == singObj ) singObj = new ThreadSafeSingleton(); 
            return singObj; 
    }   
}   


4.Double-Checked Lock:只对创建对象的语句进行同步,可以得到很好的并发度,但是可能会得到未完整初始化的对象。因为初始化需要一定时间,如当线程A未完全初始化对象时,此时对象已经不是null了,线程B在第9行判断对象不为null后就可能返回一个未完全初始化的对象。

public final class DoubleCheckedSingleton   
{   
    private static DoubleCheckedSingletonsingObj = null;   
   
    private DoubleCheckedSingleton(){   
    }   
   
    public static DoubleCheckedSingleton getSingleInstance(){   
        if(null == singObj ) { 
              Synchronized(DoubleCheckedSingleton.class){ 
                     if(null == singObj) 
                           singObj = new DoubleCheckedSingleton(); 
              } 
         } 
       return singObj; 
    }   
}   

5.Initialization-on-demand holder使用一个静态类SingletonHolder来初始化Singleton对象(注意是Singleton对象而不是SingletonHolder对象噢,原因请参看本文最开始的单例模式定义),SingletonHolder只在被使用时才被初始化,保证了性能和线程安全。并且由于java的构造方法默认是public的,需要Singleton的构造方法写成private,避免其他类直接调用Singleton的构造方法获取实例。

public class Singleton     
{     
    private Singleton(){
    }
    private static class SingletonHolder     
    {     
        public final static Singleton instance = new Singleton();     
    }         
    public static Singleton getInstance()     
    {     
        return SingletonHolder.instance;     
    }     
}   



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值