单例模式
用于创建那些在软件系统中独一无二的对象。
在实际的开发过程中,为了节约系统的资源,有时需要确保系统中某个类的实例必须是唯一的,比如:线程池、缓存、网络请求等所有的操作都需要基于唯一的实例,我们就可以使用
单例模式
。
单例模式
确保了一个类只有一个实例,而且自行实例化并且向整个系统提供这个实例,这个类被称为单例类
。它提供全局访问的方法。
单例类
的内部实现只生成一个示例,同时提供一个静态的方法,向系统提供全局访问的方法。为了防止在外部对单例类实例化,将构造方法设置为private
。单例的实现共有以下几种方式:
饿汉式的单例实现比较简单,其在类加载的时候,静态实例
instance
就已创建并初始化好了。
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 synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
双重检查将懒汉式中的方法锁改为块锁,再次调用时不会进入
synchronized
代码块中。
public class DoubleSingleton {
// 1.4及更早版本如果不加volatile关键字会导致指令重排,高版本进行了优化,所以也可以不添加
private static volatile DoubleSingleton instance;
private DoubleSingleton() {}
public static DoubleSingleton getInstance() {
if (instance == null) {
synchronized (DoubleSingleton.class) {
if (instance == null) {
instance = new DoubleSingleton();
}
}
}
return instance;
}
}
使用Java静态内部类的特性:Java 加载外部类的时候,不会创建内部类的实例,只有在外部类使用到内部类的时候才会创建内部类实例。
public class InnerClassSingleton {
private InnerClassSingleton() {}
private static class Singleton{
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return Singleton.instance;
}
}
用枚举来实现单例,是最简单的方式。这种实现方式通过 Java 枚举类型本身的特性,保证了实例创建的线程安全性和实例的唯一性。
public enum EnumSingleton {
INSTANCE; // 该对象全局唯一
}
注册式单例是通过一个注册表(容器)来存储单例实例,根据键值进行管理。
public class RegistrySingleton {
private static Map<String, RegistrySingleton> map = new HashMap<>();
static {
RegistrySingleton registrySingleton = new RegistrySingleton();
map.put(registrySingleton.getClass().getName(), registrySingleton);
}
private RegistrySingleton() {
}
public static RegistrySingleton getInstance(String className) {
if (!map.containsKey(className)) {
try {
map.put(className, (RegistrySingleton) Class.forName(className).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(className);
}
}
CAS使用乐观锁的机制,通过自旋不断尝试更新值,实现了线程安全。
public class CasSingleton {
private static final AtomicReference<CasSingleton> INSTANCE = new AtomicReference<>();
private CasSingleton() {
}
public static CasSingleton getInstance() {
while (true) {
CasSingleton singleton = INSTANCE.get();
if (singleton != null) {
return singleton;
}
singleton = new CasSingleton();
if (INSTANCE.compareAndSet(null, singleton)) {
return singleton;
}
}
}
}
例模式适用于需要全局唯一实例、提供全局访问点以及确保一致性的场景。
我会持续更新关于技术的文章❤️🤎💚🧡💛 欢迎大家点赞👍 收藏 ⭐ 关注 💡三连支持一下~~~ 查看文章过程中有问题或者有需要修改的地方,欢迎私聊我哦 🗨🗨🗨 不管世界变成什么样,我们都要加强自己自身能力~✊✊✊
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。