Java行业情景分析_Java 设计模式情景分析——单例模式
單例模式可以說是應(yīng)用最廣的模式之一,在應(yīng)用單例模式時(shí),單例對(duì)象的類必須保證只有一個(gè)實(shí)例存在,而且可以自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。一般在不能自由構(gòu)造對(duì)象的情況下,就會(huì)使用單例設(shè)計(jì)模式,例如創(chuàng)建一個(gè)對(duì)象需要消耗資源過多,還有訪問 IO 和數(shù)據(jù)庫等資源的情況。
1.單例模式
單例模式
優(yōu)點(diǎn)
1、在內(nèi)存中只有一個(gè)實(shí)例,減少了內(nèi)存開支和性能開銷;
2、可以避免對(duì)同一資源文件的同時(shí)寫操作;
3、可以在系統(tǒng)設(shè)置全局的訪問點(diǎn),優(yōu)化和共享資源訪問,例如可以設(shè)計(jì)一個(gè)單例類,負(fù)責(zé)所有數(shù)據(jù)表的映射處理;
缺點(diǎn)
1、一般沒有接口,擴(kuò)展困難;
2、單例模式如果持有 Context,很容易引發(fā)內(nèi)存泄漏,此時(shí)需要注意傳遞給單例對(duì)象的 Context 最好是 Application Context;
UML 類圖:
1.餓漢式單例
public class Singleton {
private static final Singleton instance = new Singleton(); // 句柄
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
2.懶漢式單例
優(yōu)點(diǎn)是單例只有在使用時(shí)才會(huì)被實(shí)例化;缺點(diǎn)是第一次加載反應(yīng)稍慢,每次調(diào)用 getInstance() 都進(jìn)行同步,造成了不必要的同步開銷,一般不建議使用。
public class Singleton {
private static Singleton instance; // 句柄
private Singleton() {
}
public static synchronized Singleton getInstance() { // 有同步開銷
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
3.DCL單例
Double Check Lock 實(shí)現(xiàn)單例,優(yōu)點(diǎn)是既能夠在需要時(shí)才初始化單例,又能夠保證線程安全,且單例對(duì)象初始化后調(diào)用 getInstance() 不進(jìn)行同步鎖;缺點(diǎn)是第一次加載反應(yīng)稍慢。
public class Singleton {
// volatile 禁止指令重排序優(yōu)化
private volatile static Singleton instance = null; // 句柄
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) { // 避免不必要的同步
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
4.靜態(tài)內(nèi)部類單例(推薦使用)
第一次加載不會(huì)初始化 Singleton,只有在第一次調(diào)用 Singleton 的 getInstance() 才會(huì)初始化,第一次調(diào)用會(huì)導(dǎo)致虛擬機(jī)加載 SingletonHolder 類,這種方式不僅能夠確保線程安全,也能夠保證單例對(duì)象的唯一性,同時(shí)也延遲了單例的實(shí)例化,推薦使用。
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
}
5.使用容器實(shí)現(xiàn)單例
在初始,將多種單例類型注入到一個(gè)統(tǒng)一的管理類中,在使用時(shí)根據(jù) key 獲取對(duì)象對(duì)應(yīng)類型的對(duì)象。可管理多種類型的單例,并且在使用時(shí)可以通過統(tǒng)一的接口進(jìn)行獲取操作,降低了耦合度。
public class SingletonManager {
private static Map objMap = new HashMap<>();
private SingletonManager() {
}
public static void registerInstance(String key, Object instance) {
if (objMap.containsKey(key)) {
objMap.put(key, instance);
}
}
public static Object getInstance(String key) {
return objMap.get(key);
}
}
不管以何種形式實(shí)現(xiàn)單例模式,它們的核心原理都是將構(gòu)造函數(shù)私有化,并且通過靜態(tài)方法獲取一個(gè)唯一的實(shí)例,在這個(gè)獲取的過程中必須保證線程安全、防止反序列化導(dǎo)致重新生成實(shí)例對(duì)象等問題,選擇何種取決于項(xiàng)目本身,并發(fā)環(huán)境是否復(fù)雜、單例對(duì)象等資源消耗等。
2.Spring源碼中的應(yīng)用情景
總結(jié)
以上是生活随笔為你收集整理的Java行业情景分析_Java 设计模式情景分析——单例模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 磁盘组_有效管理 ASM 磁
- 下一篇: java美元兑换,(Java实现) 美元