確保某一個類只有一個實例,並且自行實例化並向整個系統提供這個實例java
餓漢式單例模式數據庫
public class Singleton { private static final Singleton singleton = new Singleton(); // 構造器私有化,限制產生多個對象 private Singleton() {} // 對外提供靜態方法獲取實例對象 public static Singleton getInstence() { return singleton; } }
在該併發狀況下,須要注意單例模式的線程同步問題。單例模式有幾種不一樣的實現方式,餓漢式單例模式不會產生多實例的狀況,如下方式則須要考慮線程同步問題安全
懶漢式單例模式併發
public class Singleton { private static final Singleton singleton = null; // 構造器私有化,限制產生多個對象 private Singleton() {} // 對外提供靜態方法獲取實例對象 public static Singleton getInstence() { if (singleton == null) { singleton = new Singleton(); } return singleton; } }
懶漢式單例模式在低併發狀況下尚不會出現問題,若系統壓力增大,併發量增長時可能在內存中存在多個實例。如一個線程A執行到singleton = new Singleton();
但尚未得到到對象,此時對象初始化未完成,第二個線程B執行到if (singleton == null) {
那麼線程B判斷條件也爲true
,因而繼續執行下去,則A和B各得到一個對象。dom
解決單例模式線程不安全的方法,能夠在getInstence
方法前或方法內加synchronized
關鍵字來實現,建議採用餓漢式單例模式。工具
有上限的多例模式:產生固定數量對象的模式性能
public class Singleton { // 定義最多能產生的實例數量 private static int maxNumOfInstance = 2; // 定義一個列表容納全部實例 private static List<Singleton> singletonList = new ArrayList<>(); // 定義當前對象實例的序號 private static int countNumOfInstance = 0; // 產生全部的對象 static { for (int i = 0; i < maxNumOfInstance; i++) { singletonList.add(new Singleton()) } } private Singleton() {} public static Singleton getInstence() { Random random = new Random(); countNumOfInstance = random.nextInt(maxNumOfInstance); return singletonList.get(countNumOfInstance); } }
考慮到線程安全問題可使用Vector
來代替。採用有上限的多例模式,能夠在設計時決定內存中有多少個實例,方便系統擴展,修正單例可能存在的性能問題,提升系統的響應速度。如讀取文件,能夠在系統啓動時完成初始化工做,在內存中啓動固定數量的Reader
實例。測試