一、定义
确保一个类只有一个实例,并提供一个全局访问点。
要点:单件模式需要私有构造器、一个静态方法、一个静态变量
二、实现
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,双重检查发就会失效