关于单例设计模式的内容。
单例模式可以说是整个设计中最简单的模式之一,而且这种方式即使在没有看设计模式相关资料也会常用在编码开发中。
因为在编程开发中经常会遇到这样一种场景,那就是需要保证一个类只有一个实例哪怕多线程同时访问,并需要提供一个全局访问此实例的点。
综上以及我们平常的开发中,可以总结一条经验,单例模式主要解决的是,一个全局使用的类频繁的创建和消费,从而提升提升整体的代码的性能。
单例模式的实现方式比较多,主要在实现上是否支持懒汉模式、是否支持线程安全中运用各种技巧。也有一些场景会直接使用 static 静态类或属性和方法的方式进行处理,供外部调用。
接下来介绍不同方式的实现。
public class Singleton_0 {
public static Map<String, String> cache = new ConcurrentHashMap<>();
}
public class Singleton_1 {
private static Singleton_1 instance;
private Singleton_1() {
}
public static Singleton_1 getInstance() {
if (null != instance) return instance;
instance = new Singleton_1();
return instance;
}
}
public class Singleton_2 {
private static Singleton_2 instance;
private Singleton_2() {
}
public static synchronized Singleton_2 getInstance() {
if (null != instance) return instance;
instance = new Singleton_2();
return instance;
}
}
public class Singleton_3 {
private static Singleton_3 instance = new Singleton_3();
private Singleton_3() {
}
public static Singleton_3 getInstance() {
return instance;
}
}
public class Singleton_4 {
private static class SingleHolder {
private static Singleton_4 instance = new Singleton_4();
}
private Singleton_4() {
}
public static Singleton_4 getInstance() {
return SingleHolder.instance;
}
}
public class Singleton_5 {
private static volatile Singleton_5 instance;
private Singleton_5() {
}
public static Singleton_5 getInstance() {
if (null != instance) return instance;
synchronized (Singleton_5.class) {
if (null == instance) {
instance = new Singleton_5();
}
}
return instance;
}
}
public class Singleton_6 {
private static final AtomicReference<Singleton_6> INSTANCE = new AtomicReference<Singleton_6>();
private static Singleton_6 instance;
private Singleton_6() {
}
public static Singleton_6 getInstance() {
for(;;) {
Singleton_6 instance = INSTANCE.get();
if (null != instance) return instance;
INSTANCE.compareAndSet(null, new Singleton_6());
return INSTANCE.get();
}
}
public static void main(String[] args) {
System.out.println(Singleton_6.getInstance());
System.out.println(Singleton_6.getInstance());
}
}
public enum Singleton_7 {
INSTANCE;
public void doSomething() {
System.out.println("hi~");
}
}
调用方式
public class Test {
public static void main(String[] args) {
Singleton_7.INSTANCE.doSomething();
}
}
这种写法在功能上与共有域方法相近,但是它最简洁,无偿提供了串行化机制,绝对防止此类实例化,即使是在面对复杂的串行化或者反射攻击的时候。虽然这种方法还没有广泛采用,但是单元素的枚举类型已经实现了Singleton的最佳方法。
此种方法在继承场景下不可用
虽然只是一个很平常的单例模式,但在各种的实现上真的可以看到java的基本功的体现,这里包括了;懒汉、饿汉、线程是否安全、静态类、内部类、加锁、串行化等等。
在平时的开发中如果可以确保此类是全局可用不需要做懒加载,那么直接创建并给外部调用即可。但如果是很多的类,有些需要在用户触发一定的条件后(游戏关卡)才显示,那么一定要用懒加载。线程的安全上可以按需选择。
Copyright: 采用 知识共享署名4.0 国际许可协议进行许可 Links: https://lixj.fun/archives/设计模式-单例设计模式