单例模式
定义
一个类只有一个实例
原理
1、类的构造方法私有
2、只暴露一个用来获取唯一类实例的公有静态方法
实现方式
1、饿汉模式
特点:一开始就在类内部生成实例,用起来速度快,如果不用则浪费资源
public class Singleton{
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance(){
return instance;
}
}
2、懒汉模式
特点:用到在生成实例,如果不用则浪费资源,生成的时候比较慢,而且还有锁的操作,每次操作浪费相对多的资源
注意:要加锁,保证多线程情况下安全
public class Singleton{
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
3、Double Check Lock(DCL)模式
特点:饿汉与懒汉的结合,需要的时候在初始化实例,又保证线程安全,初始化后也不进行锁的操作
注意:补充volatile防止代码编译重排列
public class Singleton{
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance(){
if (instance == null) {
synchronized(Singleton.class){
if (instance == null) {
instance = new Singleton();
}
}
return instance;
}
}
4、静态内部类模式(推荐)
特点:具备DCL模式的特点,代码更优雅
public class Singleton{
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
private static class SingltonHolder {
private static Singleton instance = new Singleton();
}
}
5、枚举
特点:简单,线程安全
public enum Singleton{
INSTANCE;
}
6、容器
特点:管理多种类型的单例,统一的接口去操作,降低用户使用成本
public class Singleton{
private static Map<String,Object> map = new HashMap();
private Singleton() {}
public static void put(String key, Object instance) (){
if (!map.containKey(key)){
map.put(key, instance);
}
}
private static Object get(String key) {
return map.get(key);
}
}