Java併發基礎06 執行緒範圍內共享資料

2021-09-11 14:17:01 字數 2206 閱讀 1249

假設現在有個公共的變數 data,有不同的執行緒都可以去操作它,如果在不同的執行緒對 data 操作完成後再去取這個 data,那麼肯定會出現執行緒間的資料混亂問題,因為 a 執行緒在取 data 資料前可能 b 執行緒又對其進行了修改,下面寫個程式來說明一下該問題:

public

class

threadscopesharedata

}).start();

} }static

class

testa }

static

class

testb }}

複製**

來看一下列印出來的結果:

thread-0 has put a data: -1885917900

thread-1 has put a data: -1743455464

a get data from thread-0: -1743455464

a get data from thread-1: -1743455464

b get data from thread-1: -1743455464

b get data from thread-0: -1743455464

從結果中可以看出,兩次對 data 賦的值確實不一樣,但是兩個執行緒最後列印出來的都是最後賦的那個值,說明 thread-0 拿出的資料已經不對了,這就是執行緒間共享資料帶來的問題。

當然,我們完全可以使用 synchronized 關鍵字將run()方法中的幾行**給套起來,這樣每個執行緒各自執行完,列印出各自的資訊,這是沒問題的,確實可以解決上面的執行緒間共享資料問題。但是,這是以其他執行緒被阻塞為代價的,即 thread-0 在執行的時候,thread-1 就被阻塞了,必須等待 thread-0 執行完了才能執行。

那麼如果我想兩個執行緒同時跑,並且互不影響各自取出的值,該怎麼辦呢?這也是本文所要總結的重點,解決該問題的思想是:雖然現在都在操作公共資料 data,但是不同的執行緒本身對這個 data 要維護乙個副本,這個副本不是執行緒間所共享的,而是每個執行緒所獨有的,所以不同執行緒中所維護的 data 是不一樣的,最後取的時候,是哪個執行緒,我就從哪個執行緒中取該 data。

基於上面這個思路,我再把上面的程式做一修改,如下:

public

class

threadscopesharedata

}).start();

} }static

class

testa }

static

class

testb }}

複製**

上面程式中維護了乙個 map,鍵值對分別是執行緒和它的資料,那麼在操作 data 的時候,先把各自的資料儲存到這個 map 中,這樣每個執行緒儲存的肯定不同,當再取的時候,根據當前執行緒物件作為 key 來取出對應的 data 副本,這樣不同的執行緒之間就不會相互影響了。這個 hashmap 也需要包裝一下,因為 hashmap 是非執行緒安全的,上面的程式中,不同的執行緒有對 hashmap 進行寫操作,就有可能產生併發問題,所以也要包裝一下。最後來看一下執行結果:

thread-0 has put a data: 1817494992

thread-1 has put a data: -1189758355

a get data from thread-0: 1817494992

a get data from thread-1: -1189758355

b get data from thread-0: 1817494992

b get data from thread-1: -1189758355

就是執行緒範圍內共享資料,即同乙個執行緒裡面這個資料是共享的,執行緒間是不共享的。

這讓我聯想到了學習資料庫的時候用到的 threadlocal,運算元據庫需要 connection,如果當前執行緒中有就拿當前執行緒中存的 connection,否則就新建乙個放到當前執行緒中,這樣就不會出現問題,因為每個執行緒本身共享了乙個 connection,它不是執行緒間共享的。這也很好理解,這個 connection 肯定不能共享,假設 a 和 b 使用者都拿到這個 connection 並開啟了事務,現在 a 開始轉賬了,但是錢還沒轉好,b 轉好了關閉了事務,那麼a那邊就出問題了。

執行緒範圍內共享資料的問題就總結這麼多吧~如果有問題,歡迎指正,我們一起進步!

執行緒範圍內共享資料

我們可以先用所學知識來寫乙個 public class threadscopesharedata start static class a static class b 如果光像上面這樣寫的話,那毫無疑問,肯定是有問題的,如下圖所示並沒有實現執行緒共享 此時就實現執行緒內共享資料了 public c...

執行緒範圍內共享資料

假設現在有個公共的變數data,有不同的執行緒都可以去操作它,如果在不同的執行緒對data操作完成後再去取這個data,那麼肯定會出現執行緒間的資料混亂問題,因為a執行緒在取data資料前可能b執行緒又對其進行了修改,下面寫個程式來說明一下該問題 public class threadscopesh...

java多執行緒 執行緒範圍內共享變數(四)

什麼是執行緒範圍內共享變數?執行緒範圍內的共享變數是指對同乙個變數,幾個執行緒同時對它進行寫和讀操作,而同乙個執行緒讀到的資料就是它自己寫進去的資料。也就是說每個執行緒只能訪問他自己的,不能訪問別的執行緒的。首先我們看未實現範圍內共享變數的例子,以此來解決執行緒範圍內共享變數的解決方式 public...