您的位置:首页 > 编程语言 > Java开发

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

2014-09-08 22:35 309 查看
yao__shun__yu转载的一篇博客详细的介绍了实现单例模式的几种方法:/article/2435148.html,对性能和线程安全的阐述写得特别好。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;     
    }     
}


Double-Checked Lock:http://en.wikipedia.org/wiki/Double-checked_locking

Initialzation on Demand Holder: http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐