单例模式
2019-08-09 本文已影响0人
天空在微笑
//饿汉模式
//在类加载的时候就完成实例化,如果从始至终未使用这个实例,则会造成内存的浪费。
public class HungrySingleton {
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}
public class LazySingleton {
private static LazySingleton instance= null;
private LazySingleton() {
}
//为了处理并发,每次调用getInstance方法时都需要进行同步,会有不必要的同步开销。
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
//第一次判空,省去了不必要的同步。第二次是在Singleton等于空时才创建实例。
//使用volatile保证了实例的可见性。
//DCL在一定程度上解决了资源的消耗和多余的同步、线程安全等问题,但是在某些情况下会失效。
public class MultiCheckSingleton {
private static volatile MultiCheckSingleton instance;
private MultiCheckSingleton() {
}
public static MultiCheckSingleton getInstance() {
if (instance == null) {
synchronized (MultiCheckSingleton.class) {
if (instance == null) {
instance = new MultiCheckSingleton();
}
}
}
return instance;
}
}
//第一次调用getInstance方法时虚拟机才加载SingletonHolder并初始化sInstance,这样保证了线程安全和实例的唯一性。
public class StaticSingleton {
private StaticSingleton() {
}
public static StaticSingleton getInstance() {
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final StaticSingleton sInstance = new StaticSingleton();
}
}
//默认枚举实例的创建是线程安全的,并且在任何情况下都是单例。
//简单、可读性不高。
public class EnumSingleton {
private EnumSingleton(){}
public static EnumSingleton getInstance(){
return Singleton.INSTANCE.getInstance();
}
private static enum Singleton{
INSTANCE;
private EnumSingleton singleton;
//JVM会保证此方法绝对只调用一次
private Singleton(){
singleton = new EnumSingleton();
}
public EnumSingleton getInstance(){
return singleton;
}
}
}