線程范圍內(nèi)的共享變量

      網(wǎng)友投稿 708 2022-05-29

      1. 線程范圍內(nèi)的共享變量的概念

      假設有2個線程,一個全局變量 int data。2個線程內(nèi)的代碼共用這一個變量的聲明(data),但它們操作data時,data的值在這2個線程里是獨立的,互不影響的。我們這里所說的互不影響,不是我們之前說的syncronized,(線程1先修改data值,讀取data值,釋放鎖后,線程2才可修改data和讀取data,這樣的話data最終的值還會變?yōu)榫€程2最后修改的值)。我們現(xiàn)在要實現(xiàn)的是,線程1修改了data=1, 線程2也修改了同一個data變量的值為2,data=2,最后線程1回過頭再去讀取時,讀取出的data應該是1(它自己當時放的值就是1),線程2回頭再去讀取data時,讀取的也是它自己的值,2.? 這個data是2個線程的共享變量,但它的值在2個線程范圍內(nèi)各自是獨立的。如下圖所示:

      2. 代碼實現(xiàn)

      2.1? ?定義全局變量

      我們定義如下全局變量:

      private static Map threadData = new HashMap();

      一個map, 其中的key為正在執(zhí)行的線程對象,value就是我們在上面1中所說的data變量(整數(shù))。

      在線程1和線程2的代碼中會使用到這個全局變量threadData,通過不同的key來區(qū)分線程,從而獲取到對應線程中所操作的data變量。

      線程范圍內(nèi)的共享變量

      其本質(zhì)是利用了Map(key,value)這個數(shù)據(jù)結(jié)構(gòu),實現(xiàn)了共享變量。那么這里的共享變量應該是Map還是Map里的value(整數(shù))呢?從共享變量的角度來講是這個MAP,因為我們2個線程內(nèi)的代碼都使用了同一個變量聲明threadData,? ? ?但是從數(shù)據(jù)在線程內(nèi)獨立的角度來講,我們其實是想讓MAP中的value,這個核心數(shù)據(jù)的值在2個線程內(nèi)是獨立的。? 所以,我們還是看核心數(shù)據(jù),我認為共享變量應是Map里存儲的那個value。

      2.2? 編寫2個線程

      開啟2個線程,存儲一個data變量的值到 MAP中的value里,到時候讀取的時候,以MAP中的key來區(qū)分,讀取對應線程中 曾經(jīng)存儲過的那個data變量的值。

      package testFuture;

      import java.util.HashMap;

      import java.util.Map;

      import java.util.Random;

      public class ThreadShareData {

      private static Map threadShareData = new HashMap();

      public static void main(String[] args) {

      for(int i=0;i<2;i++){

      final int temp = i;

      new Thread(new Runnable(){

      @Override

      public void run() {

      int data = temp;

      System.out.println(Thread.currentThread().getName()

      + " has modify data :" + data);

      threadShareData.put(Thread.currentThread(), data);

      new DataReadA().get();

      }

      }).start();

      }

      }

      static class DataReadA{

      public void get(){

      int data = threadShareData.get(Thread.currentThread());

      System.out.println("DataReadA " + Thread.currentThread().getName()

      + " get data :" + data);

      }

      }

      }

      運行日志如下:

      Thread-1 has modify data :1

      Thread-0 has modify data :0

      DataReadA Thread-1 get data :1

      DataReadA Thread-0 get data :0

      我們使用for循環(huán)創(chuàng)建了2個線程,每一個線程里的run函數(shù)將 for循環(huán)的索引值作為data變量的值存儲在了threadShareData這個map里,同時這個map中的key為當前線程對象:Thread.currentThread()。

      這樣我們在調(diào)用DataReadA對象的get函數(shù)時,獲取的是每一個線程對應的value,即剛才存儲的data變量值。在這里我們可以把DataReadA對象看作是一個程序模塊。

      那我們再創(chuàng)建一個模塊,DataReadB,看看我們的運行結(jié)果。代碼和運行日志如下,

      代碼:

      package testFuture;

      import java.util.HashMap;

      import java.util.Map;

      import java.util.Random;

      public class ThreadShareData {

      private static Map threadShareData = new HashMap();

      public static void main(String[] args) {

      for(int i=0;i<2;i++){

      final int temp = i;

      new Thread(new Runnable(){

      @Override

      public void run() {

      int data = temp;

      System.out.println(Thread.currentThread().getName()

      + " has modify data :" + data);

      threadShareData.put(Thread.currentThread(), data);

      new DataReadA().get();

      new DataReadB().get();

      }

      }).start();

      }

      }

      static class DataReadA{

      public void get(){

      int data = threadShareData.get(Thread.currentThread());

      System.out.println("DataReadA " + Thread.currentThread().getName()

      + " get data :" + data);

      }

      }

      static class DataReadB{

      public void get(){

      int data = threadShareData.get(Thread.currentThread());

      System.out.println("DataReadB " + Thread.currentThread().getName()

      + " get data :" + data);

      }

      }

      }

      日志:

      Thread-0 has modify data :0

      Thread-1 has modify data :1

      DataReadA Thread-1 get data :1

      DataReadA Thread-0 get data :0

      DataReadB ?Thread-0 get data :0

      DataReadB ?Thread-1 get data :1

      我們發(fā)現(xiàn)只要是在第一個線程(Thread0)里,無論是DataReadA 還是DataReadB調(diào)用get函數(shù),讀取出來的變量值都是0,因為它當時放的就是0(日志:Thread-0 has modify data :0)。同理,

      Thread-1讀出來的值也是它當時存儲的那個變量data,如上述日志:DataReadA Thread-1 get data :1;?DataReadB ?Thread-1 get data :1。

      總結(jié):

      好了,今天線程范圍內(nèi)共享同一個變量聲明就講到這里,記住兩點就行:1. 共享同一個變量聲明; 2.? 兩個線程內(nèi)要使用的核心數(shù)據(jù)的值,是兩份,修改和讀取都互不干擾。

      任務調(diào)度

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

      上一篇:[跟著官方文檔學JUnit5][四][WritingTests][學習筆記]
      下一篇:Java面試題總結(jié)之OOA/D,UML,和XML
      相關文章
      亚洲精品乱码久久久久久中文字幕| jzzijzzij在线观看亚洲熟妇| 亚洲国产成人无码AV在线影院| 亚洲日本香蕉视频| 亚洲理论片在线观看| 亚洲成av人片不卡无码| 亚洲视频欧洲视频| 亚洲精品456在线播放| 亚洲国产成人精品无码一区二区| 久久亚洲精品无码VA大香大香| 亚洲综合日韩中文字幕v在线| 亚洲天堂中文资源| 亚洲精品自产拍在线观看动漫| 久久国产亚洲观看| 18亚洲男同志videos网站| 久久狠狠高潮亚洲精品| 亚洲视频在线观看不卡| 亚洲国产精品网站久久| 亚洲乱码一二三四五六区| 亚洲人成影院在线高清| 国产成人精品亚洲日本在线| 国产91在线|亚洲| 亚洲高清毛片一区二区| 亚洲精品永久在线观看| 色欲aⅴ亚洲情无码AV蜜桃| 婷婷亚洲综合五月天小说在线| 亚洲五月午夜免费在线视频| 中文字幕精品亚洲无线码一区应用| 在线亚洲精品自拍| 五月天网站亚洲小说| 亚洲色欲或者高潮影院| 亚洲Av无码一区二区二三区| 亚洲色偷偷综合亚洲av78| 日本系列1页亚洲系列| 精品国产亚洲男女在线线电影 | jjzz亚洲亚洲女人| 4338×亚洲全国最大色成网站| 亚洲精品狼友在线播放| 亚洲AV综合色区无码一区| 亚洲资源在线观看| 波多野结衣亚洲一级|