一、定义
确保一个类只有一个实例,并提供一个全局访问点。
要点:单件模式需要私有构造器、一个静态方法、一个静态变量
二、实现
1、同步过程
适用:应用程序可以接受getinstance造成的额外负担
优点:特容易实现
缺点:多线程下,效率下降严重
实现:
public class Singleton {
private static Singleton uniqueInstance;
private Singleton(){}
public static synchronized Singleton GetInstance(){ //使用同步标识
if(uniqueInstance==null)
{
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
2、静态初始化
适用:总是创建并适用单件实例,或者在创建和运行时方面的负担不太繁重,更急切的创建此实例。
实现:
public class Singleton {
private static Singleton uniqueInstance = new Singleton(); //JVM加载此类的,马上创建唯一单件实例
private Singleton(){}
public static Singleton GetInstance(){
return uniqueInstance;
}
}
3、双重检查
适用:杀鸡用牛刀,最完美的方法
实现:
public class Singleton {
private static Singleton uniqueInstance ;
private Singleton(){}
public static Singleton GetInstance(){ //使用同步标识
if(uniqueInstance==null)
{
synchronized(Singleton.class){ //如果不存在,就进入同步区块
if(uniqueInstance==null){
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
三、理解
1、为什么if(uniqueInstance==null)会出错
Java中,每个类加载器都定义了一个命名空间,如果有两个类加载器,不同的加载器可能会加载同一个类,从而一个类被加载多次,可能会产生多个单价并存的怪异现象。
2、单件类可不可以当超类,可不可以继承单件类
- 直接继承,会导致所有派生类共享同一个实例变量。
- 单价类构造器私有,不能用私有构造器扩展类,所以必须将单件类构造器改成公开或受保护的。
3、如果使用JVM1.2 需要建立单件注册表,被全局引用,要不然就会被GC
4、如果不是JAVA2,双重检查发就会失效