亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java多線程編程之ThreadLocal線程范圍內的共享變量

2019-11-26 15:11:29
字體:
來源:轉載
供稿:網友

模擬ThreadLocal類實現:線程范圍內的共享變量,每個線程只能訪問他自己的,不能訪問別的線程。

package com.ljq.test.thread;import java.util.HashMap;import java.util.Map;import java.util.Random;/** * 線程范圍內的共享變量 *  * 三個模塊共享數據,主線程模塊和AB模塊 *  * @author Administrator *  */public class ThreadScopeShareData {  // 準備共享的數據  private static int data = 0;  // 存放各個線程對應的數據  private static Map<Thread, Integer> threadData = new HashMap<Thread, Integer>();  public static void main(String[] args) {    // 啟動兩個線程    for (int i = 0; i < 2; i++) {      new Thread(new Runnable() {        @Override        public void run() {          // 現在當前線程中修改一下數據,給出修改信息          int data = new Random().nextInt();          // 將線程信息和對應數據存儲起來          threadData.put(Thread.currentThread(), data);          System.out.println(Thread.currentThread().getName() + " has put data :" + data);          new A().get();          new B().get();        }      }).start();    }  }  static class A {    public void get() {      int data = threadData.get(Thread.currentThread());      System.out.println("A from " + Thread.currentThread().getName()          + " get data :" + data);    }  }  static class B {    public void get() {      int data = threadData.get(Thread.currentThread());      System.out.println("B from " + Thread.currentThread().getName()          + " get data :" + data);    }  }}

運行結果:

ThreadLocal的作用和目的:
用于實現線程內的數據共享,即對于相同的程序代碼,多個模塊在同一個線程中運行時要共享一份數據,而在另外線程中運行時又共享另外一份數據。

每個線程調用全局ThreadLocal對象的set方法,就相當于往其內部的map中增加一條記錄,key分別是各自的線程,value是各自的set方法傳進去的值。在線程結束時可以調用ThreadLocal.clear()方法,這樣會更快釋放內存,不調用也可以,因為線程結束后也可以自動釋放相關的ThreadLocal變量。

ThreadLocal的應用場景:
訂單處理包含一系列操作:減少庫存量、增加一條流水臺賬、修改總賬,這幾個操作要在同一個事務中完成,通常也即同一個線程中進行處理,如果累加公司應收款的操作失敗了,則應該把前面的操作回滾,否則,提交所有操作,這要求這些操作使用相同的數據庫連接對象,而這些操作的代碼分別位于不同的模塊類中。

銀行轉賬包含一系列操作: 把轉出帳戶的余額減少,把轉入帳戶的余額增加,這兩個操作要在同一個事務中完成,它們必須使用相同的數據庫連接對象,轉入和轉出操作的代碼分別是兩個不同的帳戶對象的方法。

例如Strut2的ActionContext,同一段代碼被不同的線程調用運行時,該代碼操作的數據是每個線程各自的狀態和數據,對于不同的線程來說,getContext方法拿到的對象都不相同,對同一個線程來說,不管調用getContext方法多少次和在哪個模塊中getContext方法,拿到的都是同一個。

實驗案例:定義一個全局共享的ThreadLocal變量,然后啟動多個線程向該ThreadLocal變量中存儲一個隨機值,接著各個線程調用另外其他多個類的方法,這多個類的方法中讀取這個ThreadLocal變量的值,就可以看到多個類在同一個線程中共享同一份數據。

實現對ThreadLocal變量的封裝,讓外界不要直接操作ThreadLocal變量。
對基本類型的數據的封裝,這種應用相對很少見。
對對象類型的數據的封裝,比較常見,即讓某個類針對不同線程分別創建一個獨立的實例對象。

package com.ljq.test.thread; import java.util.Random; /** * ThreadLocal類及應用技巧 * * 將線程范圍內共享數據進行封裝,封裝到一個單獨的數據類中,提供設置獲取方法 * 將該類單例化,提供獲取實例對象的方法,獲取到的實例對象是已經封裝好的當前線程范圍內的對象 */public class ThreadLocalTest {   private static ThreadLocal<Integer> x = new ThreadLocal<Integer>();  //private static ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>();  public static void main(String[] args) {    for(int i=0;i<2;i++){      new Thread(new Runnable(){        @Override        public void run() {          int data = new Random().nextInt();          System.out.println(Thread.currentThread().getName() + " has put data :" + data);          x.set(data);                     /*                   MyThreadScopeData myData = new MyThreadScopeData();          myData.setName("name" + data);          myData.setAge(data);          myThreadScopeData.set(myData);          */          MyThreadScopeData.getThreadInstance().setName("name" + data);          MyThreadScopeData.getThreadInstance().setAge(data);          new A().get();          new B().get();        }      }).start();    }  }     //使用獲取到的線程范圍內的對象實例調用相應方法  static class A{    public void get(){      int data = x.get();      System.out.println("A from " + Thread.currentThread().getName() + " get data :" + data);             /*           MyThreadScopeData myData = myThreadScopeData.get();      System.out.println("A from " + Thread.currentThread().getName()          + " getMyData: " + myData.getName() + "," + myData.getAge());      */      MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();      System.out.println("A from " + Thread.currentThread().getName()          + " getMyData: " + myData.getName() + "," + myData.getAge());    }  }     //使用獲取到的線程范圍內的對象實例調用相應方法  static class B{    public void get(){      int data = x.get();          System.out.println("B from " + Thread.currentThread().getName() + " get data :" + data);             MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();      System.out.println("B from " + Thread.currentThread().getName()          + " getMyData: " + myData.getName() + "," + myData.getAge());         }     }}  class MyThreadScopeData {   // 單例  private MyThreadScopeData() {  }   // 提供獲取實例方法,不加synchronized關鍵字表示線程各拿各自的數據,互不干擾  public static/* synchronized */MyThreadScopeData getThreadInstance() {    // 從當前線程范圍內數據集中獲取實例對象    MyThreadScopeData instance = map.get();    if (instance == null) {      instance = new MyThreadScopeData();      map.set(instance);    }    return instance;  }   // 將實例對象存入當前線程范圍內數據集中  private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();   private String name;  private int age;   public String getName() {    return name;  }   public void setName(String name) {    this.name = name;  }   public int getAge() {    return age;  }   public void setAge(int age) {    this.age = age;  }}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲va码欧洲m码| 91夜夜揉人人捏人人添红杏| 亚洲国产第一页| 欧美日韩美女在线观看| 91av在线播放| 亚洲香蕉伊综合在人在线视看| www.99久久热国产日韩欧美.com| 欧美精品aaa| 精品一区二区电影| 久久久久久香蕉网| 亚洲成人xxx| 国产成人综合一区二区三区| www.国产精品一二区| 日本高清+成人网在线观看| 亚洲视频视频在线| 国产91精品不卡视频| 亚洲性av网站| 91在线视频一区| 亚洲视频在线免费观看| 欧美激情亚洲视频| 国产成人精品亚洲精品| 亚洲最新在线视频| 国产视频久久网| 亚洲国产精彩中文乱码av| xvideos亚洲| 亚洲自拍小视频免费观看| 国产免费成人av| 一道本无吗dⅴd在线播放一区| 日韩av在线影院| 久久国产精品电影| 欧美影院成年免费版| 亚洲天堂av电影| 国产精品丝袜白浆摸在线| 欧美视频第一页| 国产成人短视频| 国产精品第100页| 久久久999国产| 91精品视频大全| 日韩一级黄色av| 欧美电影在线观看完整版| 日韩av日韩在线观看| xxx一区二区| 永久免费看mv网站入口亚洲| 欧美激情亚洲自拍| 韩国一区二区电影| 欧美丝袜第一区| 国产成人激情小视频| 国产日韩中文字幕在线| 亚洲视频在线免费观看| 国产日韩综合一区二区性色av| 孩xxxx性bbbb欧美| 国产视频自拍一区| 国产日产欧美a一级在线| 久久久日本电影| 97国产精品久久| 国产精品视频资源| 日韩在线一区二区三区免费视频| 国产日韩av在线播放| 亚洲视频精品在线| 亚洲伊人久久大香线蕉av| 日韩欧美在线视频免费观看| 国产精品久久久久久久久| 日韩欧美国产一区二区| 欧美电影免费观看高清| 成人h猎奇视频网站| 色综合视频网站| 欧美精品久久久久久久久| 国产色婷婷国产综合在线理论片a| 国产综合视频在线观看| 国产亚洲精品综合一区91| 欧美黑人性视频| 日韩精品在线免费播放| 欧美激情在线视频二区| 国产69精品久久久久99| 亚洲网站在线看| 中文字幕精品—区二区| 亚洲精品乱码久久久久久按摩观| 午夜剧场成人观在线视频免费观看| 亚洲a成v人在线观看| 欧美中文在线免费| 国产日韩欧美电影在线观看| 久国内精品在线| 日韩av黄色在线观看| 欧美在线视频播放| 欧美在线影院在线视频| 欧美黑人又粗大| 国产精品三级美女白浆呻吟| 久久久国产视频| 超碰精品一区二区三区乱码| 亚洲精品福利在线| 久久久久国产精品一区| 97在线精品国自产拍中文| 国产精品久久久久aaaa九色| 久久影视电视剧免费网站清宫辞电视| 欧美肥臀大乳一区二区免费视频| 亚洲福利在线看| 欧美亚洲另类制服自拍| 欧美日本啪啪无遮挡网站| 日韩欧美成人免费视频| 成人精品一区二区三区电影黑人| 欧美成人激情图片网| 欧美激情综合色| 国产精品福利久久久| 日韩激情视频在线播放| 一区二区三区日韩在线| 91在线观看免费高清完整版在线观看| 日韩美女在线观看| 国产精品入口尤物| 国产精品视频一| 欧美另类精品xxxx孕妇| 性欧美亚洲xxxx乳在线观看| 日韩黄色高清视频| 日韩av在线天堂网| 欧美日韩中文字幕综合视频| 欧美性猛交xxxx富婆| 国产亚洲欧美日韩一区二区| 91在线观看欧美日韩| 欧美专区第一页| 久久久亚洲影院你懂的| 亚洲free性xxxx护士白浆| 中文字幕av一区二区三区谷原希美| 欧美激情高清视频| 成人精品视频99在线观看免费| 久久手机精品视频| 日韩精品中文字幕在线播放| 欧美日韩在线视频首页| 国产啪精品视频网站| 国产成人精品国内自产拍免费看| 国产精品老牛影院在线观看| 91黄色8090| 97色在线观看| 日韩中文在线不卡| 日韩av在线免费观看| 97视频网站入口| 日韩欧美在线网址| 福利视频一区二区| 国产精品ⅴa在线观看h| 91亚洲一区精品| 欧美电影《睫毛膏》| 青青a在线精品免费观看| 亚洲国产精品悠悠久久琪琪| 欧美乱妇高清无乱码| 在线播放国产一区中文字幕剧情欧美| 欧美日韩高清在线观看| www.欧美精品| 黄色一区二区三区| 日韩欧美视频一区二区三区| 欧美日韩免费看| 亚洲精品自产拍| 欧美日韩亚洲天堂| 日韩av成人在线观看| 久久中文字幕国产| 国产精品jvid在线观看蜜臀| 欧美精品免费播放| 一区三区二区视频| 俺也去精品视频在线观看| 国产在线精品一区免费香蕉| 欧美大片在线看免费观看| 2019av中文字幕| 欧美精品999| 亚洲最大中文字幕| 91久久精品国产91久久| 亚洲一区二区三区乱码aⅴ| 国产精品一区久久久|