多个线程操作不同实例对象。多个线程要操作同一对象,要保证对象的唯一性,所以对象的实例化时,只实例化一次
实现方式:
第一种 饿汉模式:
public class HungrySingleton {
private static HungrySingleton instance=new HungrySingleton();
public HungrySingleton getInstance(){
return instance;
}
}
这种方式在类加载的时候直接实例化,线程是安全的,但当堆中对象过多时会引起内存溢出的问题
第二种 懒汉模式:DCL+volatile
public class HoonSingleton {
private static volatile HoonSingleton instanceHoonSingleton=null;
public HoonSingleton getInstance(){
if(null==instanceHoonSingleton){
synchronized (HoonSingleton.class) {
if(null==instanceHoonSingleton){
instanceHoonSingleton=new HoonSingleton();
}
}
}
return instanceHoonSingleton;
}
}
这种方式实现懒加载+线程同步,但是当单例对象中的属性有多个时,会因为运行时指令重排可能导致空指针异常需要加上volatile关键字,并且中间的synchronize的锁机制,性能会受影响。
第三种方式 Holder:
public class Holder {
private static class HolderIn{
private static Holder instance=new Holder();
}
public static Holder getInstance(){
return HolderIn.instance;
}
}
利用静态内部类的延迟加载,实现运行时加载且只加载一次,实际中运用比较多
第四种 枚举:
public class EnumSingleton {
private enum enumHolder{
Instance;
private EnumSingleton instance;
private EnumSingleton getInstance() {
instance=new EnumSingleton();
return instance;
}
}
public static EnumSingleton getInstance(){
return enumHolder.Instance.getInstance();
}
}
把静态内部类设为枚举类,代码优雅,同时实现延迟加载一次,使用也比较多。