单例模式是在学习Java设计模式过程中接触最多的一个模式。单例模式的写法有好几种形式,虽然形式各异,但目的都是为了保证 一个类仅有一个实例,并提供一个访问它的全局入口(getInstance())。
饿汉式
public class Singleton {
private static Singleton instance =
new Singleton();
private Singleton() {};
public Singleton
getInstance() {
return instance;
}
}
懒汉式(添加了“双检锁”,解决数据同步问题)
public class Singleton {
private static Singleton instance;
private Singleton() {};
public Singleton
getInstance() {
if(instance ==
null) {
synchronized (Singleton.class) {
if(instance ==
null) {
instance =
new Singleton();
}
}
}
return instance;
}
}
静态内部类中创建单例类实例
public class Singleton {
private Singleton() {};
private static class SingletonHolder {
private static final Singleton INSTANCE =
new Singleton();
}
public Singleton
getInstance() {
return SingleHolder.INSTANCE;
}
}
上面这种实现单例的方式,同样无法避免通过Java的反射机制调用私有的构造函数创建出第二个单例类的实例。为了避免这个问题,我们可以去修改构造函数,使它在被要求创建第二个实例时抛出异常。
public class Singleton {
private static boolean isCreated;
private Singleton() {
synchronized(Singleton.class) {
if(isCreated) {
throw new RuntimeException(
"单例模式被攻击了!");
}
else {
isCreated =
true;
}
}
}
private static class SingletonHolder {
private static final Singleton INSTANCE =
new Singleton();
}
public Singleton
getInstance() {
return SingletonHolder.INSTANCE;
}
}
枚举实现单例
public enum Singleton {
INSTANCE;
}
单元素的枚举类型是目前实现单例模式的最佳实践,即可以防止反射攻击,可以防止序列化破坏单例模式。
参考文章 如何防止单例模式被 JAVA 反射攻击 singleton模式四种线程安全的实现
转载请注明原文地址: https://ju.6miu.com/read-39641.html