【并發技術06】線程范圍內共享數據

      網友投稿 664 2025-03-31

      假設現在有個公共的變量 data,有不同的線程都可以去操作它,如果在不同的線程對 data 操作完成后再去取這個 data,那么肯定會出現線程間的數據混亂問題,因為 A 線程在取 data 數據前可能 B 線程又對其進行了修改,下面寫個程序來說明一下該問題:

      public?class?ThreadScopeShareData?{????private?static?int?data?=?0;//公共的數據????public?static?void?main(String[]?args)?{????????for(int?i?=?0;?i?

      我們來看一下打印出來的結果:

      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

      【并發技術06】線程范圍內共享數據

      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?{????private?static?int?data?=?0;//公共的數據????//定義一個Map以鍵值對的方式存儲每個線程和它對應的數據,即Thread:data????private?static?Map?threadData?=?Collections.synchronizedMap(new?HashMap());???????public?static?void?main(String[]?args)?{????????for(int?i?=?0;?i?

      上面程序中維護了一個 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 那邊就出問題了。線程范圍內共享數據的問題就總結這么多吧。

      HashMap 任務調度

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel表單元格移動(excel單元格內容移動)
      下一篇:Excel快速統計身份證信息方法介紹
      相關文章
      亚洲AV无码专区在线厂| 亚洲国产精品ⅴa在线观看| 亚洲天堂在线视频| 亚洲AⅤ男人的天堂在线观看| 亚洲熟女精品中文字幕| 亚洲午夜精品久久久久久app| 亚洲无吗在线视频| 亚洲性色AV日韩在线观看| 亚洲精品无码专区在线播放| 亚洲欧洲日产国码久在线| 亚洲熟妇无码AV| 色综合久久精品亚洲国产| 亚洲av综合av一区二区三区| 亚洲AV日韩AV无码污污网站| 亚洲av成人中文无码专区| 久久久久亚洲AV无码去区首| 国产成人综合亚洲绿色| 亚洲av手机在线观看| 久久国产成人精品国产成人亚洲| 久久亚洲中文字幕精品一区四| 亚洲综合激情另类专区| 亚洲理论电影在线观看| 亚洲AV日韩AV永久无码免下载| 久久精品国产亚洲av日韩| 亚洲91av视频| 78成人精品电影在线播放日韩精品电影一区亚洲 | 亚洲av无码国产精品夜色午夜| 久久亚洲精品成人综合| 久久精品九九亚洲精品| 亚洲人成黄网在线观看| 亚洲依依成人亚洲社区| 国产成人综合亚洲| 国产日产亚洲系列最新| 亚洲国产一二三精品无码| 亚洲精品福利视频| 亚洲国产中文在线二区三区免| 亚洲日本国产综合高清| 国产亚洲精品精品精品| 国外亚洲成AV人片在线观看| 亚洲爆乳无码专区| 亚洲熟妇色自偷自拍另类|