文章目錄
-
-
- 單例模式
-
- 1. 分析
- 2. 示例
-
- 2.1 懶漢式
- 2.2 懶漢式雙重鎖檢測
- 2.3 靜态内部類單例模式
- 2.4 餓漢式
- 2.5 容器式
- 2.6 ThreadLocal式
-
單例模式
單例模式的7種寫法
1. 分析
- 定義:包證一個類僅有一個執行個體,并提供一個全局通路點
- 類型:
建立型
适用場景:
- 想確定任何情況下都絕對隻有一個執行個體
優點:
- 在記憶體中隻有一個執行個體,減少了記憶體開銷
- 可以避免對資源的多重占用
- 設定全局通路點,嚴格控制通路
缺點:
- 沒有接口,擴充困難
重點:
- 私有構造器
- 線程安全
- 延遲加載
- 序列化和反序列化安全
- 反射
2. 示例
2.1 懶漢式
public class LazySingleton {
private static LazySingleton lazySingleton = null;
private LazySingleton() {
}
public synchronized static LazySingleton getInstance() {
if (lazySingleton == null) {
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
2.2 懶漢式雙重鎖檢測
public class LazyDoubleCheckSingleton {
private volatile static LazyDoubleCheckSingleton lazyDoubleCheckSingleton = null;
private LazyDoubleCheckSingleton() {
}
public static LazyDoubleCheckSingleton getInstance() {
if (lazyDoubleCheckSingleton == null) {
synchronized (LazyDoubleCheckSingleton.class) {
if (lazyDoubleCheckSingleton == null) {
lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton();
//1.配置設定記憶體給這個對象
//2.初始化對象
//3.設定lazyDoubleCheckSingleton 指向剛配置設定的記憶體位址
}
}
}
return lazyDoubleCheckSingleton;
}
}
2.3 靜态内部類單例模式
public class StaticInnerClassSingleton {
private StaticInnerClassSingleton() {
}
private static class InnerClass {
private static StaticInnerClassSingleton staticInnerClassSingleton = new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance() {
return InnerClass.staticInnerClassSingleton;
}
}
2.4 餓漢式
- 方式1
public class HungrySingleton {
private final static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return hungrySingleton;
}
}
- 方式2,使用靜态代碼塊
public class HungrySingleton {
private final static HungrySingleton hungrySingleton;
static {
hungrySingleton = new HungrySingleton();
}
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return hungrySingleton;
}
}
解決序列化與反序列化對象不一緻問題
public class HungrySingleton implements Serializable {
private final static HungrySingleton hungrySingleton;
static {
hungrySingleton = new HungrySingleton();
}
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return hungrySingleton;
}
private Object readResolve() {
return hungrySingleton;
}
}
實作接口,添加
Serializable
方法
readResolve
2.5 容器式
public class ContainerSingleton {
private ContainerSingleton() {
}
private static Map<String, Object> singletonMap = new ConcurrentHashMap<>();
public static void putInstance(String key, Object instance) {
if (StringUtils.isNotBlank(key) && instance != null) {
if (!singletonMap.containsKey(key)) {
singletonMap.put(key, instance);
}
}
}
public static Object getInstance(String key) {
return singletonMap.get(key);
}
}
2.6 ThreadLocal式
public class ThreadLocalInstance {
private ThreadLocalInstance() {
}
private static final ThreadLocal<ThreadLocalInstance> threadLocal = new ThreadLocal<ThreadLocalInstance>() {
@Override
protected ThreadLocalInstance initialValue() {
return new ThreadLocalInstance();
}
};
public ThreadLocalInstance getInstance() {
return threadLocal.get();
}
}