Paste_Image.png
- 單例模式用于限制一個類的對象個數,確保在JVM中只有一個類的對象。通常用于在應用程序中只有需要有一個全局對象的情形下。
- 比如:Singleton pattern is used for logging, drivers objects, caching and thread pool
- Singleton design pattern is used in core java classes also, for example java.lang.Runtime
,java.awt.Desktop.
單例模式的實現方法:
單例模式有不同的實現方法,但都遵循以下的步驟:
- 將構造方法私有化,防止其他類使用。
- private static的該類的唯一對象。
- 提供一個public static 的getInstance()方法供外界調用。
大致就是以上的三個步驟,但是會根據對象實例化方式的不同而產生不同單例模式的實現方式。
單例模式的不同實現方法:
Eager initialization
package com.journaldev.singleton;
public class EagerInitializedSingleton {
private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();
//private constructor to avoid client applications to use constructor
private EagerInitializedSingleton(){}
public static EagerInitializedSingleton getInstance(){
return instance;
}
}
優缺點:
--這是一種很簡單的實現方法,當class被編譯的時候,該對象就已經產生
-- 通過代碼可以看出,這種實現的方式:在客戶端調用之前已經對單例對象進行了實例化的操作。所以如果客戶端應用不需要該對象的話那么就產生了一種浪費。
--所以,當我們使用單例的時候不需要操作很多資源的話,那么可以推薦使用這一種簡單的創建方式。但是通常情況下,我們創建單例會使用系統的資源和文件,比如: File System, Database connections,此時我們應該選擇在調用時才創建對象的單例模式。
Lazy Initialization##
package com.journaldev.singleton;
public class LazyInitializedSingleton {
private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){}
public static LazyInitializedSingleton getInstance(){
if(instance == null){
instance = new LazyInitializedSingleton();
}
return instance;
}
}
- 這種模式的創建:知道客戶端需要該對象的時候才會第一次被創建
- 這種模式在單線程之下是安全的,但是當多線程的時候,多個線程同時對其 進行讀寫操作會可能會產生錯誤。
Thread Safe Singleton##
The easier way to create a thread-safe singleton class is to make the global access method synchronized, so that only one thread can execute this method at a time. General implementation of this approach is like the below class.
package com.journaldev.singleton;
public class ThreadSafeSingleton {
private static ThreadSafeSingleton instance;
private ThreadSafeSingleton(){}
public static synchronized ThreadSafeSingleton getInstance(){
if(instance == null){
instance = new ThreadSafeSingleton();
}
return instance;
}
}
--線程安全的單例模式比較簡單的實現是對getInstance方法加上synchronized加上鎖,使得一次只能被同一線程訪問。