单例模式的讨论

来源:互联网 发布:汽车租赁软件 编辑:程序博客网 时间:2024/05/21 21:36

单例相对于静态变量的优势:

(1),可以支持延迟加载

(2),可以支持多态

最简单的单例模式

public class Singleton {

    private static final Singleton instance = new Singleton();

    

    private Singleton() {

    }

    

    public static Singleton getInstance(){

        return instance;

    }

}

缺点:一开始就初始化,有可能浪费资源

  有可能一开始的时候初始化所需的信息不足


为避免浪费资源,使用延迟加载:

public class Singleton {

    private static Singleton instance = null;

    

    private Singleton() {

    }

    

    public static Singleton getInstance(){

        if(instance == null){

            instance = new Singleton();

        }

        return instance;

    }

}

好处:用到的时候才初始化,避免浪费。

缺点:非线程安全,多线程环境下有可能产生多个实例


解决线程安全性:

public class Singleton {

    private static Singleton instance = null;

   

    private Singleton() {   

    }

    

    public static Singleton getInstance(){

        if(instance == null){

            synchronized(Singleton.class){

                if(instance == null){

                    instance = new Singleton();

                }

            }

        }

        return instance;

    }

}

缺点:资源消耗比较大

      有可能引入空指针


可以使用静态内部类来实现单例的延迟夹杂,

 public class Foo {     

private static class LazyFoo {  

public static Foo foo = new Foo();  

 }  

  

public static Foo getInstance() {  

return LazyFoo.foo;  

  }  

}  

静态内部类只有当有引用时内部类才会被装载,从而实现延迟加载


当需求是需要该类有唯一实例,但该类的初始化需要外部信息

public class Singleton {

    private static Singleton instance = null;

    private static A iA = null;

    private Singleton(A a) {

        iA = a;

    }

    

    public static Singleton getInstance(A a){

        if(instance == null){

            instance = new Singleton(a);

        }

        return instance;

    }

}

缺点:所有使用该实例的对象都被要求知道A

或者:

public class Singleton {

    private static Singleton instance = null;

    private static A iA = null;

    private Singleton() {

        

    }

    

    public static Singleton getInstance(A a){

        if(instance == null){

            instance = new Singleton();

        }

        return instance;

    }

    

    public static void setA(A a){        

        iA = a;

    }

}

缺点:获得该实例之前必须设置相关的外部信息


单例模式相对于静态变量来说有支持子类化的优势

由外部信息获取单例的子类:

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {

        

    }

    

    public static Singleton getInstance(int aParam){

        if(instance == null){

            if(aParam == 0){

                instance = new SubSingleton1();

            }else if(aParam == 1){

                instance = new SubSingleton2();

            }

            else{

                instance = new Singleton();

            }

           

        }

        return instance;

    }  

}

原创粉丝点击