執行緒安全的單利

2021-06-28 05:55:58 字數 1810 閱讀 8766

老大一直說要用這個來做面試題,讓面試的人來寫乙個執行緒安全的單例模式,感覺自己還沒掌握,把 head first--design patterns 找了出來,以下大部分內容抄襲自這本書,略有增刪改。

1. 全域性變數的缺點:

必須在程式一開始就建立好物件,如果程式在這次的執行過程中又一直沒用到它,就非常耗費資源。

2. 經典的單例模式實現:

public

class

singleton    

//注意這個方法也是靜態的 

public

"color: #ff0000"

>

static

singleton getinstance()    

return

uniqueinstance;   

}   

}  

單例常被用來管理共享的資源,例如資料庫連線、執行緒池、快取、登錄檔。

單例模式確保乙個類只有乙個例項,並提供乙個全域性訪問點。

這個模式的問題:在多執行緒時,並不能保證這個類只被例項化一次。

3. 處理多執行緒:

public class singleton   

//注意這個方法也是靜態的

public

static

"color:#ff0000;"

>

synchronized

singleton getinstance()   

return

uniqueinstance;  

}  }  

通過增加synchronized關鍵字到getinstance()方法中,迫使每個執行緒在進入方法之前,要先等別的執行緒離開該方法。也就是說,不會有兩個執行緒可以同時進入這個方法。

這種方法存在的問題:只有第一次執行此方法時,才真正需要同步。換句話說,一旦設定好uniqueinstance變數,就不再需要同步這個方法了。之後每次呼叫這個方法,同步都是一種浪費。

4.改善多執行緒

4.1 如果getinstance()的效能對應用程式不是很關鍵,就不用優化了

4.2 使用急切建立例項,而不用延遲例項化的做法

public

class

singleton    

public

static

singleton getinstance()    

}  標紅的語句在靜態初始化器(static initializer)中建立單例,這保證了執行緒安全。

利用這個做法,jvm在載入這個類時馬上建立此唯一的單件例項。jvm保證任何執行緒訪問uniqueinstance靜態變數之前,一定先建立些例項。

4.3 用「雙重檢查加鎖」,在getinstance()中減少使用同步

首先檢查例項是否已經建立,如果尚未建立,才進行同步。這樣一來,只有第一次會同步,這正是我們想要的。

public

class

singleton   

public

static

singleton getinstance()   

}  return

uniqueinstance;  

}  }  

在最開始如果有1、2、3個執行緒走到了(1)處,假設1進入了同步塊,2、3等待。1例項化後,2進入同步塊,發現uniqueinstance已經不為空,跳出同步塊。接著3進入,又跳出同步塊。

volatile關鍵字確保:當uniqueinstance變數被初始化成singleton例項時,多個執行緒正確地uniqueinstance變數。如果效能是你關心的重點,那麼這個做法可以幫你大大地減少getinstance()的時間耗費。

執行緒安全的單利模式

public class singleton public static singleton getsin view code 上述 中的乙個缺點是該類載入的時候就會直接new 乙個靜態物件出來,當系統中這樣的類較多時,會使得啟動速度變慢 現在流行的設計都是講 延遲載入 我們可以在第一次使用的時候才...

Spring bean的單利模式和非單利模式

spring bean預設情況下所有bean是單一的,即單利模式。中表示 scope singleton singleton表示spring容器中只會建立乙個叫做mybean的bean物件。所有的對該bean的請求都由該物件來處理,這個bean物件就是共享的,就是說這個bean是非執行緒安全的。既然...

執行緒安全與非執行緒安全的區別

執行緒安全 是多執行緒訪問時,採用加鎖機制,當乙個執行緒訪問該類的某個資料時,進行保護,其他執行緒不能進行訪問直到該執行緒讀取完,其他執行緒才可使用。不會出現資料不一致或者資料汙染。非執行緒安全 是多執行緒訪問時,不提供資料訪問保護,有可能出現多個執行緒先後更改資料造成所得到的資料是髒資料。所得資料...