<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jclown

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      3 Posts :: 0 Stories :: 6 Comments :: 0 Trackbacks

          ThreadLocal是線程變量的意思,不是本地線程。它可以為線程分配特有的空間(與線程自身的堆棧不同,是線程對象在內存中的一個Map),使得線程可以通過這個空間隨時獲取自己相關的上下文信息。

    ThreadLocal 內幕

    ThreadLocal很容易讓使用者誤解(以前我就誤解了),因為在這個類中定義了一個靜態的包級可見的內部類ThreadLocalMap,同時ThreadLocal對外提供了get和set方法。那么set的時候就是把當前線程對象作為ThreadLocalMap的key,把傳入set方法的值作為value存儲起來;get的時候通過獲取當前線程對象,然后到ThreadLocalMap中取得對應的value。這種認識是表面的很容易理解的方式,但是也是錯誤的理解。

    每個Thread類中都有ThreadLocal.ThreadLocalMap的兩個成員,分別是threadlocals與inheritableThreadLocals。前者用來存儲當前線程的相關數據信息,后者用來存儲從父線程中繼承或者說拷貝過來的相關數據信息。這兩個區域也就是前面提到的線程的特別存儲區域,但是如何操作它們?JDK中的設計并不是讓用戶直接操作當前線程來存取數據,而是讓用戶操作ThreadLocal來對當前線程的這兩個Map進行存取(個人認為這樣設計是出于安全性與易用性考慮,主要是Map中的key值需要固定才能取到同一對象),同時放置在這兩個Map中的key值就是ThreadLocal對象自身,value由用戶傳入。


    ThreadLocal 進階

    ThreadLocal為線程獨占某些對象或者資源提供了新的手段,ThreadLocal與線程堆棧都是用來存取線程私有數據的區域,別的線程無法觸碰這兩個區域,但是二者確有不同的生命周期。這個可以這樣理解,線程跨多個方法調用的時候,方法作為Frame不斷的進棧和出棧(方法的調用與返回),同時出棧的時候方法中的臨時變量數據會被回收,在這個線程的堆棧中消失,所以方法中的局部變量是無法在線程調用過程中穿透,除非是傳遞局部的引用類型變量,但是這也意味著方法接口都要額外接收新的參數(早期系統中傳遞JDBC數據庫連接的方式)。而ThreadLocal不同,準確地說是線程中的ThreadLocalMap不同,線程對象中的ThreadLocalMap對象是伴隨整個線程對象生命周期的,線程可以在任何需要的時候通過它來獲取相關數據,這為線程獨占數據提供了一種更加優雅的方式。只不過這一切都是通過ThreadLocal來操作的而已,同時ThreadLocal自身也作為不同線程中的ThreadLocalMap中的key來映射存入的value。

    ThreadLocal 應用

    public class ThreadWriter

    {

       private static final ThreadLocal<FileWriter> local = new

    ThreadLocal<FileWriter>();

        public void write(String s)

        {

           try

           {

               getFileWriter().write(s);

           }

           catch(IOException e)

           {

               //igore

           }

        }

        private FileWriter getFileWriter()

        {

           FileWriter fw = local.get();

           if (null == fw)

           {

               try

               {

    fw = new FileWriter(Thread.currentThread().getName() + "-info.txt", true);

                  local.set(fw);

               }

               catch(IOException e)

               {

                 //igore

               }

           }

           return fw;

        }

    }

    這里說明幾個問題:

    1、 ThreadLocal對象只有一份,它將作為不同線程中的ThreadLocalMap對象的key,所映射的值是不同文件路徑的FileWriter對象。只不過不同 線程中的ThreadLocalMap中的key值都一樣,但是因為在不同的ThreadLocalMap中,不會有任何影響,反而這樣的方式為每個線程中ThreadLocalMap對象中的key值生成省去了很多功夫,這是一個很精妙的設計,用戶在間接使用ThreadLocalMap的時候,不需要感知key是什么,就可以方便地存取。

    2、 一份ThreadLocal對象只能映射一種資源。如需要映射多種資源的話,定義多個ThreadLocal成員。

    3、 local.set(fw); 這句代碼表示將local自身作為key,fw作為value,存儲在調用這行代碼的線程中的ThreadLocalMap對象中。

    FileWriter fw = local.get(); 這句代碼表示將local自身作為key,從當前線程的ThreadLocalMap對象中取出屬于自己獨占的FileWriter對象。 

    posted on 2010-09-19 20:06 jclown 閱讀(2223) 評論(2)  編輯  收藏 所屬分類: Java 雜談

    Feedback

    # re: 理解 ThreadLocal 2010-09-21 12:35 Chase
    不錯不錯,這個又讓我加深了對  回復  更多評論
      

    # re: 理解 ThreadLocal[未登錄] 2010-09-24 19:31 steven
    我是這樣理解的. 不知道對不對.
    某個類需要為每一個訪問的線程都提供一份實例,他需要把這份實例保存在ThreadLocal里面, 可供線程上下文可以隨時訪問這個實例.  回復  更多評論
      


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲精品无码永久在线观看男男| 亚洲成a人一区二区三区| 亚洲日韩精品射精日| 青青草国产免费国产是公开 | 亚洲三级视频在线观看| 99视频全部免费精品全部四虎 | 亚洲国产精品福利片在线观看| 成人免费观看男女羞羞视频| 亚洲区小说区图片区| 99麻豆久久久国产精品免费| 亚洲精品成人无码中文毛片不卡| 成人久久免费网站| 久久久婷婷五月亚洲97号色 | 亚洲精品成人网站在线观看 | 亚洲午夜未满十八勿入网站2| 日本在线看片免费| 亚洲成a人片在线观看中文!!! | 久久久亚洲精品蜜桃臀| 日韩av无码免费播放| 精品亚洲成a人片在线观看少妇| 黄色网址免费观看| 亚洲国产精品嫩草影院| 亚洲国产精品综合久久网络| 久久久久成人精品免费播放动漫| 亚洲黄色网址大全| 日韩在线免费电影| 中国一级毛片视频免费看| 1区1区3区4区产品亚洲| 看全色黄大色大片免费久久| 一级毛片一级毛片免费毛片| 亚洲精品高清视频| 成人免费无毒在线观看网站| 国产精品高清免费网站| 亚洲日韩在线视频| 免费v片视频在线观看视频| 久久黄色免费网站| 亚洲aⅴ无码专区在线观看春色| 亚洲韩国精品无码一区二区三区| 噼里啪啦电影在线观看免费高清 | 亚洲日本国产乱码va在线观看| 国产精品99久久免费|