定义:单例模式(Singleton Pattern):确保一个类中只有一个实例,并提供全局访问点(方法)。
作用:提供全局访问点、节约系统资源、控制实例化过程和实现懒加载。
使用场景:
-
需要频繁创建和销毁的对象,例如缓存、线程池、注册表等。
-
需要控制资源的访问,例如文件操作、数据库连接等。
-
需要保证对象的唯一性和一致性,例如配置信息、全局变量等。
/**
* 单例模式——饿汉式
* 类加载的时候自行实例化,无论是否使用都会创建,线程安全
*/
public class HungrySingleton {
private static final HungrySingleton INSTANCE = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return INSTANCE;
}
}
/**
* 单例模式——懒汉式
* 使用的时候才会创建,多线程情况下创建的对象不一样,线程不安全
*/
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
/**
* 单例模式——静态内部类(此处暂未考虑Java反射技术对单例模式的影响)
* 在内部类被加载和初始化时,才创建INSTANCE实例对象
* 静态内部类不会自动随着外部类的加载和初始化而初始化,它是要去单独加载和初始化的
* 因为内部类加载和初始化时创建的,因此是线程安全的
*/
public class StaticInnerSingleton {
private StaticInnerSingleton() {
}
public static class StaticInner {
private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();
}
public static StaticInnerSingleton getInstance() {
return StaticInner.INSTANCE;
}
}
/**
* 单例模式——DCL懒汉式(Double Checked Locking:双重检测锁模式)
* 既能合理的分配内存资源又可以保证线程安全
*/
public class DCL {
// new 一个对象的过程,有三个步骤
// 1.内存分配
// 2.初始化
// 3.返回对象引用
// 由于JVM指令重排优化,可能会使得2、3两步顺序发生变化,说明这里不是一个原子性操作
// 因为 new DCL()不是一个原子操作,这里使用volatile修饰dclSingleton 防止指令重排
private volatile static DCL dclSingleton;
private DCL() {
}
public static DCL getInstance() {
if (dclSingleton == null) {
synchronized (DCL.class) {
if (dclSingleton == null) {
dclSingleton = new DCL();
}
}
}
return dclSingleton;
}
}
/**
* 单例模式——枚举类
* 枚举类型是Java 5中新增特性的一部分,也是类的一种,自带单例模式
* 可以防止Java反射技术对单例模式的破坏
*/
public enum EnumSingleton {
INSTANCE;
public static EnumSingleton getInstance(){
return EnumSingleton.INSTANCE;
}
}