1、延迟实例化方式:(懒汉模式)
public class Singleton {
private static Singleton uniqueInstance;
private Singleton(){
}
public static Singleton getInstance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
对资源敏感的对象特别重要,缺点是线程不安全。
2、延迟实例化方式:(懒汉模式)
public class Singleton {
private static Singleton uniqueInstance;
private Singleton(){
}
public synchronized static Singleton getInstance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
线程安全了,但是效率低,资源利用率不高,因为只有第一次执行此方法时,才需要同步,99%的场合用不到同步,而同步一个方法可能会造成程序执行效率下降100倍。
3、非延迟实例化方法:(饿汉模式)
public class Singleton3 {
private static Singleton3 uniqueInstance = new Singleton3();
private Singleton3(){
}
public static Singleton3 getInstance(){
return uniqueInstance;
}
}
4、双重检查加锁:
public class Singleton4 {
private volatile static Singleton4 uniqueInstance;
private Singleton4(){
}
public static Singleton4 getInstance(){
if(uniqueInstance == null){
synchronized (Singleton4.class){
if(uniqueInstance == null){
uniqueInstance = new Singleton4();
}
}
}
return uniqueInstance;
}
}
volatile关键字确保:当uniqueInstance变量被初始化成Singleton4实例时,多个线程能正确处理uniqueInstance变量。
注意:
1)如果不是采用第五版的Java 2,双重检查加锁实现会失效;
2)如果使用多个类加载器,可能会导致单件失效而产生多个实例;
3)如果使用JVM1.2或之前的版本,必须建立单件注册表,以免GC将单件回收。