淺談Java併發編程系列(一)—— 如何保證線程安全

線程安全類

保證類線程安全的措施:

  1. 不共享線程間的變量;數據庫

  2. 設置屬性變量爲不可變變量;編程

  3. 每一個共享的可變變量都使用一個肯定的鎖保護;安全

保證線程安全的思路:

1. 經過架構設計

經過上層的架構設計和業務分析來避免併發場景。好比須要用多線程或分佈式集羣統計一堆用戶的相關統計值,因爲用戶的統計值是共享數據,所以須要保證線程安全。從業務上分析出用戶之間的數據並不共享,所以能夠設計一個規則來保證一個用戶的計算工做和數據訪問只被一個線程或一臺機器完成,這樣從設計上避免了接下來可能的併發問題。多線程

2. 保證類無狀態

有狀態會限制橫向擴展能力,也可能產生併發問題。若是類是無狀態的,那它永遠是線程安全的。所以在設計階段儘量用無狀態的類來知足業務需求。架構

3. 區別原子操做和複合操做

常見的複合操做包括check-then-act, i++等。雖然check-then-act從表面上看很簡單,但卻廣泛存在與咱們平常的開發中,特別是在數據庫存取這一塊。好比咱們須要在數據庫裏存一個客戶的統計值,當統計值不存在時初始化,當存在時就去更新。若是不把這組邏輯設計爲原子性的就頗有可能產生出兩條這個客戶的統計值。
在單機環境下處理這個問題還算容易,經過鎖或者同步來把這組複合操做變爲原子操做,但在分佈式環境下就不適用了。通常狀況下是經過在數據庫端作文章,好比經過惟一性索引或者悲觀鎖來保障其數據一致性。固然任何方案都是有代價的,這就須要具體狀況下來權衡。併發

4. 鎖

使用鎖應注意:分佈式

  • 每一個共享變量必須由一個肯定的鎖保護。性能

  • 使用鎖會有性能損失.net

  • 鎖不能解決在分佈式環境共享變量的併發問題。線程

參考:探索併發編程(二)------寫線程安全的Java代碼

相關文章
相關標籤/搜索