小編給大家分享一下Java單例模式的實現方式有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
需要確保某個類只要一個對象,或創建一個類需要消耗的資源過多,如訪問IO和數據庫操作等,這時就需要考慮使用單例模式了。
將構造函數訪問修飾符設置為private
通過一個靜態方法或者枚舉返回單例類對象
確保單例類的對象有且只有一個,特別是在多線程環境下
確保單例類對象在反序列化時不會重新構建對象
/**
* 餓漢式實現單例模式
*/
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}/**
* 懶漢式實現單例模式
*/
public class Singleton {
private static Singleton instance;
private Singleton() {
}
// synchronized方法,多線程情況下保證單例對象唯一
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}getInstance()方法中添加了synchronized關鍵字,使其變成一個同步方法,目的是為了在多線程環境下保證單例對象唯一。
優點: 只有在使用時才會實例化單例,一定程度上節約了資源。
缺點: 第一次加載時要立即實例化,反應稍慢。每次調用getInstance()方法都會進行同步,這樣會消耗不必要的資源。這種模式一般不建議使用。
/**
* DCL實現單例模式
*/
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
// 兩層判空,第一層是為了避免不必要的同步
// 第二層是為了在null的情況下創建實例
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}優點: 資源利用率高,既能夠在需要的時候才初始化實例,又能保證線程安全,同時調用getInstance()方法不進行同步鎖,效率高。
缺點: 第一次加載時稍慢,由于Java內存模型的原因偶爾會失敗。在高并發環境下也有一定的缺陷,雖然發生概率很小。
DCL模式是使用最多的單例模式實現方式,除非代碼在并發場景比較復雜或者JDK 6以下版本使用,否則,這種方式基本都能滿足需求。
/**
* 靜態內部類實現單例模式
*/
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
/**
* 靜態內部類
*/
private static class SingletonHolder {
private static Singleton instance = new Singleton();
}
}第一次加載Singleton類時不會初始化instance,只有在第一次調用getInstance()方法時,虛擬機會加載SingletonHolder類,初始化instance。
這方式既保證線程安全,單例對象的唯一,也延遲了單例的初始化,推薦使用這種方式來實現單例模式。
/**
* 枚舉實現單例模式
*/
public enum SingletonEnum {
INSTANCE;
public void doSomething() {
System.out.println("do something");
}
}默認枚舉實例的創建是線程安全的,即使反序列化也不會生成新的實例,任何情況下都是一個單例。
優點: 簡單!
import java.util.HashMap;
import java.util.Map;
/**
* 容器類實現單例模式
*/
public class SingletonManager {
private static Map<String, Object> objMap = new HashMap<String, Object>();
public static void regsiterService(String key, Object instance) {
if (!objMap.containsKey(key)) {
objMap.put(key, instance);
}
}
public static Object getService(String key) {
return objMap.get(key);
}
}SingletonManager可以管理多個單例類型,使用時根據key獲取對象對應類型的對象。這種方式可以通過統一的接口獲取操作,隱藏了具體實現,降低了耦合度。
以上是“Java單例模式的實現方式有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。