ThreadLocal與synchronized

          Posted on 2009-08-25 20:36 林光炎 閱讀(971) 評論(0)  編輯  收藏 所屬分類: JAVA

          相關文章:  
          正確理解ThreadLocal
          ThreadLocal與synchronized

          推薦圈子: Pipboy
          更多相關推薦
          昨天上Java版塊逛了一圈,一個2萬5千人瀏覽的帖子引起了偶滴注意 ThreadLocal與synchronized ,9頁以上的回復,足見大家對這個問題的興趣。

          老實說,從看到這個帖子的題目開始,就覺得帖子的作者估計是在概念上有所混淆了,于是乎想寫個咚咚,同大家分享一下自己的心得。

          帖子上,討論的人很多,高手不乏,各抒己見,但不知新手們看明白沒有,因此,這里偶以最簡潔列表方式來說一說相關問題。

          1.區別ThreadLocal 與 synchronized

          ThreadLocal是一個線程隔離(或者說是線程安全)的變量存儲的管理實體(注意:不是存儲用的),它以Java類方式表現;
          synchronized是Java的一個保留字,只是一個代碼標識符,它依靠JVM的鎖機制來實現臨界區的函數、變量在CPU運行訪問中的原子性。
          兩者的性質、表現及設計初衷不同,因此沒有可比較性。

          2.理解ThreadLocal中提到的變量副本
          事實上,我們向ThreadLocal中set的變量不是由ThreadLocal來存儲的,而是Thread線程對象自身保存。當用戶調用ThreadLocal對象的set(Object o)時,該方法則通過Thread.currentThread()獲取當前線程,將變量存入Thread中的一個Map內,而Map的Key就是當前的ThreadLocal實例。請看源碼,這是最主要的兩個函數,能看出ThreadLocal與Thread的調用關系:

          Java代碼
          public void set(T value) {   
                  Thread t = Thread.currentThread();   
                  ThreadLocalMap map = getMap(t);   
                  if (map != null)   
                      map.set(this, value);   
                  else  
                      createMap(t, value);   
          }   
            
          ThreadLocalMap getMap(Thread t) {   
                  return t.threadLocals;   
          }  
          public void set(T value) {
                  Thread t = Thread.currentThread();
                  ThreadLocalMap map = getMap(t);
                  if (map != null)
                      map.set(this, value);
                  else
                      createMap(t, value);
          }

          ThreadLocalMap getMap(Thread t) {
                  return t.threadLocals;
          }

          (有興趣的朋友可以閱讀Java的ThreadLocal源碼)因此,我們可以知道,所謂的變量副本,即是對Object Reference(對象引用)的拷貝。

          3.理解Thread和 ThreadLocal對變量的引用關系
          實際上Thread和ThreadLocal對變量引用關系就像是坐標系中的X軸和Y軸,是從兩個維度上來組織對變量的引用的。

          首先說Thread。 我們知道一個ThreadOne的執行會貫穿多個方法MethodA、MethodB、MethodC這些方法可能分布于不同的類實例。假設,這些方法分別使用了ThreadLocalA、ThreadLocalB、ThreadLocalC來保存線程本地變量,那么這些變量都存于ThreadOne的Map中,并使用各自的ThreadLocal實例作為key。 因此,可以認為,借助ThreanLocal的set方法,在X軸上,Thread橫向關聯同一線程上下文中來自多個Method的變量引用副本。


           


          接著說ThreadLocal。 一個MethodA中的X變量將被多個線程ThreadOne、ThreadTwo、ThreadThree所訪問。假設MethodA使用ThreadLocal存儲X,通過set方法,以ThreadLocal作為key值,將不同線程來訪時的不同的變量值引用保存于ThreadOne、ThreadTwo、ThreadThree的各自線程上下文中,確保每個線程有自己的一個變量值。因此,可以認為,ThreadLocal是以Method為Y軸,縱向關聯了處于同一方法中的不同線程上的變量。


           

          希望能對大家有所幫助,這樣可以少走很多彎路哦。

          本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/yangairong1984/archive/2008/04/15/2294572.aspx

          posts - 104, comments - 33, trackbacks - 0, articles - 0

          Copyright © 林光炎

          主站蜘蛛池模板: 池州市| 永年县| 南岸区| 阿巴嘎旗| 囊谦县| 聂拉木县| 罗源县| 镇雄县| 平顶山市| 闻喜县| 临湘市| 曲松县| 台湾省| 读书| 开封市| 吉首市| 江安县| 寻甸| 迁西县| 顺义区| 庄浪县| 荆门市| 石狮市| 淮南市| 托克逊县| 高清| 大新县| 依兰县| 平罗县| 资源县| 阳高县| 安塞县| 开封县| 瑞丽市| 高唐县| 札达县| 梨树县| 新乡县| 深水埗区| 灵石县| 尼勒克县|