单例模式的讨论
单例相对于静态变量的优势:
(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;
}
}
补充:综合编程 , 其他综合 ,