java併發的三種處理方式

Java併發的處理也算是老生常談的一個問題,處理方法很多,但是一旦出現差池,後果也是相當嚴重,所以還是得好好補補,之前也是模糊瞭解而已,這段時間靜下心來學習,也算是初有成見。

這裏我就來說說Java併發的三種處理方式

1. volatile修飾共享變量
2. ThreadLocal操作共享數據
3. synchronize鎖操作共享變量

使用場景:

  1. volatile
    多線程情況下 :一個線程修改共享變量,多個線程讀取,舉例:volatile修飾變量作爲線程停止的標識符。
    注意:
    如果修改操作是基於當前值的時候就不能使用volatile,就比如i++;因爲volatile雖然保證禁止重排序,但是並不是原子性操作,當最後寫回主內存之前會出現問題。
    具體參考:(這兩篇看完基本就懂volatile了,很精闢)
    https://www.jianshu.com/p/ac42412fa0cc
    https://www.cnblogs.com/churao/p/8494160.html

  2. ThreadLocal
    犧牲空間,創建額外的空間來存儲共享變量的副本,線程內訪問副本,互不影響。
    每一個 Thread 都有一個 ThreadLocalMap ,這個 Map 以 ThreadLocal 對象爲鍵,以要保存的線程局部變量爲值。這樣就做到了爲每個線程保存不同的副本。
    目的是將共享變量轉變爲 “線程局部變量”,相當於將共享變量分配給併發的線程,線程內操作變量,互不影響。舉例spring中訪問數據庫需要使用模板類,用的是同一個連接資源,照例來說只能供一個線程使用,但是通過ThreadLocal即可實現多線程併發,每個線程內部都維繫了一個同一個連接資源的副本。
    具體參考:(也是一篇神文,包懂)
    https://www.iteye.com/topic/1123824

  3. synchronize
    這個也是最常用的,直接鎖住,犧牲時間,同一時刻只有一個線程可以訪問。

最後總結:

  1. volatile 是爲了保證資源被多個線程併發正確操作。(可見性,禁止重排序)
  2. ThreadLocal是爲了保證資源不被多線程同時操作。(犧牲空間)
  3. synchronize是爲了多線程下 同一時刻只有一個線程操作資源。(犧牲時間,保證原子性)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章