目錄
1、前言
2、基本語法
2.1、懶漢式單例
2.2、餓漢式單例
2.3、雙重檢驗鎖單例模式
2.4、靜態(tài)內(nèi)部類單例模式
2.5、枚舉單例模式
2.6、ThreadLocal單例模式
2.7、注冊單例模式
3、使用場景
4、使用示例
5、常見問題
5、總結(jié)
1、前言
單例模式是一種設(shè)計模式,它確保一個類只能創(chuàng)建一個實例,并提供一種全局訪問這個實例的方式。在Java中,單例模式可以通過多種方式來實現(xiàn),其中最常見的是使用私有構(gòu)造函數(shù)和靜態(tài)方法實現(xiàn)
2、基本語法
在Java中,實現(xiàn)單例模式的方式有多種,其中最常見的實現(xiàn)方式包括以下幾種:
2.1、懶漢式單例
懶漢式單例模式指的是在第一次使用單例對象時才創(chuàng)建實例。具體實現(xiàn)方式是在getInstance()方法中判斷實例是否已經(jīng)被創(chuàng)建,如果沒有則創(chuàng)建一個新實例并返回。懶漢式單例模式的缺點是線程不安全,在多線程環(huán)境下可能會創(chuàng)建多個實例。
public class Singleton {
private static Singleton instance;
private Singleton() {
// 私有構(gòu)造函數(shù)
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2.2、餓漢式單例
餓漢式單例模式指的是在類加載時就創(chuàng)建實例,因此也被稱為靜態(tài)單例模式。具體實現(xiàn)方式是將實例化語句放在靜態(tài)代碼塊中。由于在類加載時就創(chuàng)建了實例,因此不存在線程安全性問題。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
// 私有構(gòu)造函數(shù)
}
public static Singleton getInstance() {
return instance;
}
}
2.3、雙重檢驗鎖單例模式
雙重檢驗鎖單例模式是一種線程安全的單例模式實現(xiàn)方式,它通過使用synchronized關(guān)鍵字來確保線程安全性。具體實現(xiàn)方式是在getInstance()方法中添加雙重檢驗鎖,這可以避免不必要的鎖競爭和實例化。
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
// 私有構(gòu)造函數(shù)
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
2.4、靜態(tài)內(nèi)部類單例模式
靜態(tài)內(nèi)部類單例模式是一種比較常用的單例模式實現(xiàn)方式,它利用了靜態(tài)內(nèi)部類只會在被使用時才會加載的特點,從而避免了餓漢式單例模式的資源浪費和懶漢式單例模式的線程不安全問題。
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton() {
// 私有構(gòu)造函數(shù)
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
2.5、枚舉單例模式
枚舉單例模式是一種更為簡單和安全的單例模式實現(xiàn)方式,它利用了Java中枚舉類型本身就是單例的特點。枚舉單例模式是一種天然線程安全的單例模式實現(xiàn)方式,而且可以防止反射和序列化等攻擊。
public enum Singleton {
INSTANCE;
// 其他方法
}
2.6、ThreadLocal單例模式
ThreadLocal單例模式是一種可以在多線程環(huán)境下確保單例對象的線程安全單例模式實現(xiàn)方式。具體實現(xiàn)方式是在ThreadLocal中保存單例對象,每個線程都有自己的ThreadLocal副本,從而避免了線程安全性問題。
public class Singleton {
private static final ThreadLocal<Singleton> INSTANCE = new ThreadLocal<Singleton>() {
@Override
protected Singleton initialValue() {
return new Singleton();
}
};
private Singleton() {
// 私有構(gòu)造函數(shù)
}
public static Singleton getInstance() {
return INSTANCE.get();
}
}
2.7、注冊單例模式
注冊式單例模式指的是通過一個注冊表來管理所有單例對象,從而實現(xiàn)單例模式。具體實現(xiàn)方式是在一個靜態(tài)的Map中保存所有單例對象,然后在需要使用單例對象時通過Map來獲取。
public class Singleton {
private static Map<String, Singleton> instances = new HashMap<>();
private Singleton() {
// 私有構(gòu)造函數(shù)
}
public static Singleton getInstance(String name) {
if (!instances.containsKey(name)) {
instances.put(name, new Singleton());
}
return instances.get(name);
}
}
3、使用場景
單例模式通常在需要確保全局只有一個實例的場景中使用,例如:
- 線程池:在多線程環(huán)境下,線程池需要保證只有一個實例。
- 數(shù)據(jù)庫連接池:同樣地,數(shù)據(jù)庫連接池也需要保證只有一個實例。
- 日志對象:日志對象通常是全局可見的,因此需要保證只有一個實例。
- 配置文件:在某些情況下,需要全局共享的配置文件也需要保證只有一個實例。
4、使用示例
下面是一個簡單的例子,演示如何使用單例模式實現(xiàn)線程池:
public class ThreadPool {
private static ThreadPool instance;
private ThreadPool() {
// 初始化線程池
}
public static synchronized ThreadPool getInstance() {
if (instance == null) {
instance = new ThreadPool();
}
return instance;
}
// 線程池相關(guān)的方法
}
在上述代碼中,我們使用synchronized關(guān)鍵字來保證getInstance()方法的線程安全性。這意味著每次只有一個線程可以訪問getInstance()方法,從而避免了多個線程同時創(chuàng)建線程池實例的問題。
5、常見問題
單例模式的實現(xiàn)有一些常見問題,需要注意:文章來源:http://www.zghlxwxcb.cn/news/detail-701623.html
- 線程安全性:如上所述,如果多個線程同時訪問getInstance()方法,可能會導(dǎo)致多個實例的創(chuàng)建。因此,需要確保getInstance()方法是線程安全的,可以通過synchronized關(guān)鍵字來實現(xiàn)。
- 序列化問題:如果單例類實現(xiàn)了Serializable接口,那么在反序列化時可能會創(chuàng)建多個實例。解決方法是在類中添加readResolve()方法,并返回單例實例。
- 反射問題:通過反射機制,可以調(diào)用私有構(gòu)造函數(shù)創(chuàng)建實例。解決方法是在構(gòu)造函數(shù)中添加判斷,如果已經(jīng)存在實例則拋出異常
5、總結(jié)
單例模式是一種非常常用的設(shè)計模式,在多線程環(huán)境下,它可以確保只有一個實例被創(chuàng)建,并提供一種全局訪問這個實例的方式。在Java中,可以通過私有構(gòu)造函數(shù)和靜態(tài)方法實現(xiàn)單例模式。在實現(xiàn)單例模式時,需要注意線程安全性、序列化問題以及反射問題。盡管單例模式非常有用,但也有一些缺點,例如它可能導(dǎo)致代碼變得更加復(fù)雜,而且在多線程環(huán)境下可能會影響性能。因此,在使用單例模式時需要根據(jù)具體情況進(jìn)行權(quán)衡。文章來源地址http://www.zghlxwxcb.cn/news/detail-701623.html
到了這里,關(guān)于【設(shè)計模式】單例設(shè)計模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!