单例模式
Singleton Pattern ,是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点。属于创建者模式
1、饿汉式
优点:执行效率高
缺点:类加载就初始化,不管用不用都占用着空间,浪费内存
public class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
}
2、懒汉式
优点:解决了恶汉式的无赖
缺点:并发过大时,会出现线程不安全
public class Singleton {
private static final Singleton singleton = null;
private Singleton(){}
public static Singleton getInstance(){
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
3、双重检查锁
优点:解决了懒汉式的线程不安全问题
缺点:并发过大时,会导致程序性能下降。
public class Singleton {
// volatile 禁止重排,避免出现重排 实例未加载
private static volatile Singleton singleton = null;
private Singleton(){}
public static Singleton getInstance(){
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
4、静态内部类
- 解决饿汉的内存浪费、双重锁的性能问题,
- 缺点:内部类不能接受传参数
public class Singleton {
private Singleton(){}
public static final Singleton getInstance(){
return Lazy.SINGLETON;
}
private static class Lazy{
private static final Singleton SINGLETON = new Singleton();
}
}
5、防反射
- 无敌版
public class Singleton {
private Singleton(){
if (Lazy.SINGLETON != null) {
throw new RuntimeException("不可以哦")
}
}
public static final Singleton getInstance(){
return lazy.SINGLETON;
}
private static class Lazy{
private static final Singleton SINGLETON = new Singleton();
}
}
6、注册式
- 枚举实现
public enum Singleton {
INSTANCE;
public static Singleton getInstance() {
return INSTANCE;
}
}
- 容器实现
public class Singleton {
private Singleton() {}
private static Map<String, Object> ioc = new ConcurrentHashMap<>();
public static Object getBean(String className) {
synchronized (ioc) {
if (!ioc.containsKey(className)) {
Object obj = null;
try {
obj = Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return obj;
} else {
return ioc.get(className);
}
}
}
}
7、线程实现
- 仅能保证当前线程是唯一的
public class Singleton {
private static final ThreadLocal<Singleton> threadLocalSingleton
= new ThreadLocal<Singleton>() {
@Override
protected Singleton initialValue() {
return new Singleton();
}
};
private Singleton() {}
private static Map<String, Object> ioc = new ConcurrentHashMap<>();
public static Object getBean(String className) {
return threadLocalSingleton.get();
}
}
ps:
还有一种破坏单例:序列化。
解决方案:重写readResolve方法