单例模式

总结单例的几种写法:

1 静态内部类,这种方式利用了classloder的机制来保证初始化instance时只有一个线程,支持延迟加载和线程安全

public class CommonRpcHttpServer{   

    private static class SingletonHolder {
        static final CommonRpcHttpServer instance = new CommonRpcHttpServer();
    }

    public static CommonRpcHttpServer getInstance() {
        return SingletonHolder.instance;
    }

}

2 (懒汉,线程不安全)

public class ProcessFactory {

    private static ProcessFactory singleton = null;

    public ProcessFactory() {
        super();
    }

    public static ProcessFactory singleton() {
        ProcessFactory.singleton = (ProcessFactory) Class.forName("ProcessFactory").newInstance();
        return singleton;

//return new ProcessFactory()

//通过class.forname().newInstance()和new ()方式的效果一致,前者进行实例化的好处是解耦,增加代码的复用性和扩展性,但只能调用无参的构造函数,后者 强类型,效率高,可以调用任何public构造函数,但强耦合。
    }

3(懒汉,线程安全),增加同步块约束

public class ProcessFactory {

    private static ProcessFactory singleton = null;

    public ProcessFactory() {
        super();
    }

    public static synchronized QuoteProcessFactory singleton() {
        ProcessFactory.singleton = (ProcessFactory) Class.forName("ProcessFactory").newInstance();
        return singleton;
    }

4 饿汉,静态域直接初始化,不支持延迟加载

public class ProcessFactory {

    private static ProcessFactory singleton = new ProcessFactory() ;

   //private static ProcessFactory singleton = null;

   //{singleton = new ProcessFactory() ;}

    public ProcessFactory() {
        super();
    }

    public static ProcessFactory singleton() {
        return singleton;
    }

5 双重校验锁,注意volatile 修饰单例对象,否则还是会出现同步问题。在JDK1.5及其后续版本中,扩充了volatile语义,系统将不允许对 写入一个volatile变量的操作与其之前的任何读写操作 重新排序,也不允许将 读取一个volatile变量的操作与其之后的任何读写操作 重新排序。

public class ProcessFactory {

   private static volatile ProcessFactory singleton = null;
    public ProcessFactory() {
        super();
    }
    public static ProcessFactory singleton() {

    if(singleton == null){

      synchronized(ProcessFactory.class){

        if(singleton == null){

          return new ProcessFactory ();

        }

      }

   }

}
总结: 总的来说,有五种写法,懒汉,恶汉,双重校验锁,枚举(用的比较少,未举例)和静态内部类,个人倾向静态内部类。

延伸连接,双重检验锁的弊端:http://www.xker.com/page/e2011/0422/101056.html

posted @ 2015-03-25 11:23  xiongjianjun  阅读(98)  评论(0编辑  收藏  举报