定义
应用程序运行期,只有一个类的实例对象
实现方案
1.私有类的构造方法
基本实现
步骤:
1.私有类的构造方法
2.创建私有静态的类的实例对象
3.创建静态方法,对外提供类的实例对象
public class Singleton {
private Singleton(){}
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
}
优化
1.懒加载(延迟加载)
public class Singleton {
private Singleton(){}
private static Singleton instance;
public static Singleton getInstance(){
if(instance==null) {
instance = new Singleton();
}
return instance;
}
}
2.保证线程安全:Double-Checked Locking(双重检查锁定)
public class Singleton {
private Singleton(){}
private static volatile Singleton instance;
public static Singleton getInstance(){
if(instance==null) {
sychronized(Singleton.class) {
if(instance==null) {
instance = new Singleton();
}
}
}
return instance;
}
}
缺陷
1.反射破坏单例对象的唯一性
利用反射调用私有的构造函数
2.高并发导致的DCL失效
高并发的情况下,不能保证对象的唯一性
原因:
1.new操作本身并不是原子操作
2.Java的内存模型允许指令重排
2.静态内部类
实现原理
利用类加载机制来实现
类加载阶段创建单例对象,因此是线程安全的
基本实现
步骤:
1.私有类的构造方法
2.创建静态内部类,在其中创建单例对象
3.创建静态方法,对外提供类的单例对象
public class Singleton {
private Singleton(){}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton()
}
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
缺陷
反射破坏单例对象的唯一性
利用反射调用私有的构造函数
3.枚举类
枚举实例的创建是线程安全的,并且在任何情况下它都是一个单例
public enum Singleton {
INSTANCE;
public Singleton() {
... ...
}
}
总结
只有使用枚举类,能够确保单例对象的唯一性
本文详细探讨了Java中实现单例模式的三种方法:私有构造方法(包含懒加载和双检锁优化)、静态内部类以及枚举类型。分别阐述了每种方法的基本实现、优化措施以及潜在的缺陷,如反射破坏单例、高并发下的线程安全问题等。最后总结指出,使用枚举类型是确保单例唯一性的最佳实践。
1239

被折叠的 条评论
为什么被折叠?



