定義: 保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。
功能:單例模式是用來(lái)保證這個(gè)類在運(yùn)行期間只會(huì)被創(chuàng)建一個(gè)類實(shí)例,另外,單例模式還提供了一個(gè)全局唯一訪問這個(gè)類實(shí)例的訪問點(diǎn),就是getInstance方法
單例模式有兩種,可以分為餓漢式和懶漢式;
餓漢式:
private static Singleton uniqueInstance = new Singleton();空間換時(shí)間
懶漢式
private static Singleton uniqueInstance = null;時(shí)間換空間
餓漢式是線程安全的,因?yàn)樘摂M機(jī)保證只會(huì)裝載一次,在裝載類的時(shí)候是不會(huì)發(fā)生并發(fā)的。
不加同步的懶漢式是線程不安全的。比如,有兩個(gè)線程,一個(gè)是線程A,一個(gè)是線程B,它們同時(shí)調(diào)用getInstance方法,就可能導(dǎo)致并發(fā)問題。
開發(fā)中我們使用較多的是餓漢式,當(dāng)然懶漢式也是會(huì)使用的,但是需要進(jìn)行處理,使其是線程安全的;
方法: 加上synchronized同步鎖機(jī)制
public static synchronized Singleton getInstance(){? }
但這樣會(huì)降低整個(gè)訪問的速度,而且每次都要判斷。所以我們可以用雙重檢查加鎖。
雙重加鎖機(jī)制,指的是:并不是每次進(jìn)入getInstance方法都需要同步,而是先不同步,進(jìn)入方法過后,先檢查實(shí)例是否存在,如果不存在才進(jìn)入下面的同步塊,這是第一重檢查。進(jìn)入同步塊后,再次檢查實(shí)例是否存在,如果不存在,就在同步的情況下創(chuàng)建一個(gè)實(shí)例。這是第二重檢查。
雙重加鎖機(jī)制的實(shí)現(xiàn)會(huì)使用一個(gè)關(guān)鍵字volatile,它的意思是:被volatile修飾的變量的值,將不會(huì)被本地線程緩存,所有對(duì)該變量的讀寫都是直接操作共享內(nèi)存,從而確保多個(gè)線程能正確的處理該變量。
?????????? /**
?????????????? * 雙重檢查加鎖的單例模式
??????????????? * @author dream
??????????????? *
??????????? */
????????????? public class Singleton {
??????????????? /**
???????????????? * 對(duì)保存實(shí)例的變量添加volitile的修飾
?????????????? */
???????????????? private volatile static Singleton instance = null;
????????????????? private Singleton(){
?????????????? }
??????????????? public static Singleton getInstance(){
?????????????? //先檢查實(shí)例是否存在,如果不存在才進(jìn)入下面的同步塊
???????????? if(instance == null){
??????????????? //同步塊,線程安全的創(chuàng)建實(shí)例
???????????????? synchronized (Singleton.class) {
????????????????? //再次檢查實(shí)例是否存在,如果不存在才真正的創(chuàng)建實(shí)例
????????????????? instance = new Singleton();
?? ? ? ? ? ? ? ? ?? ?? }
?????????????? }
???????????? return instance;
??????????????? }
??????????? }
??????????????? ###一種更好的單例實(shí)現(xiàn)方式
??????????????? public class Singleton {
???????????????????? /**
???????????????????? * 類級(jí)的內(nèi)部類,也就是靜態(tài)類的成員式內(nèi)部類,該內(nèi)部類的實(shí)例與外部類的實(shí)例
?????????????????? * 沒有綁定關(guān)系,而且只有被調(diào)用時(shí)才會(huì)裝載,從而實(shí)現(xiàn)了延遲加載
??????????????? * @author dream
??????????????????? *
?????????????? */
????????????????? private static class SingletonHolder{
???????????????? /**
????????????? * 靜態(tài)初始化器,由JVM來(lái)保證線程安全
??????????????? */
??????????????? private static final Singleton instance = new Singleton();
???????????? }
???? ?? ??? /**
????????????????? * 私有化構(gòu)造方法
???????????????? */
???????????????? private Singleton(){
????????????????????? }
???????????????? public static Singleton getInstance(){
?????????????? return SingletonHolder.instance;
????????????? }
???????? }
###何時(shí)選用單例模式 當(dāng)需要控制一個(gè)類的實(shí)例只能有一個(gè),而且客戶只能從一個(gè)全局訪問點(diǎn)訪問它時(shí),可以選用單例模式,這些功能恰好是單例模式要解決的問題。
單例模式的使用舉例:
1.Application,Android中的Application類就是單例的;