原文: Gerrard_Fenghtml
單例: 確保一個類只有一個實例,並提供一個全局訪問點設計模式
--《Head First 設計模式》多線程
其目的在於減小系統對於同一個對象的建立和銷燬,從而減小內存的開銷。併發
實現單例的方法:線程
要了解如何保證一個類始終只有一個實例,首先須要知道,一個類是怎麼建立實例的:Java 中建立對象的4種方式設計
以上文章,總結了4種在Java中建立對象的方法,其中構造器是最經常使用的方法。code
在實現單例時,須要思考是否在這幾種狀況下對於單例的保證,另一方面,也要考慮到多線程併發訪問的狀況。htm
其中 Object 的 clone() 方法,其設計的意義與單例徹底背道而馳,能夠這麼理解:若是一個類實現了 Cloneable 接口,那麼設計者自己就不但願這個類是一個單例,因此就不作考慮了。對象
如下是6種實現單例模式的方法:blog
這6種方式的具體實現和優劣會在各自的章節中具體闡明。
另外,若是一個類實現了 Serializable 接口,那麼指望這個類成爲單例還須要一些額外的操做:
一:餓漢模式(Eager)
思想:
餓漢模式是最常說起的2種單例模式之一,其核心思想,是類持有一個自身的 instance 屬性,而且在申明的同時當即初始化。
同時,類將自身的構造器權限設爲 private,防止外部代碼建立對象,對外只提供一個靜態的 getInstance() 方法,做爲獲取單例的惟一入口。
public final class EagerSingleton { private static final EagerSingleton instance = new EagerSingleton(); private EagerSingleton() { if (instance != null) { throw new IllegalStateException(); } } public static final EagerSingleton getInstance() { return instance; } }
爲何在私有構造器中加入對 instance 屬性的空校驗? 爲了阻止反射的入侵,從而打破單例。
多線程的狀況下會不會打破單例? 不會,由於 EagerSingleton 是在加載類的同時進行對象的建立,因此即便在多線程併發的狀況下,仍然能夠保證單例。
優點?劣勢?
優點:對象屬於類,不須要考慮多線程
劣勢:在加載類的同時建立單例對象,若是這個對象不是馬上須要使用的,會額外增長內存的消耗。