類在Spring,Hibernate等框架中起到了很大的作用,對于其工作原理,很多網上的文章分析的不夠徹底,甚至有些誤解。首先,為了解釋ThreadLocal類的工作原理,必須同時介紹與其工作甚密的其他幾個類(內部類)1.ThreadLocalMap2.Thread可能有人會覺得Thread與ThreadLocal有什么關系,其實真正的奧秘就在Threa" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

ThreadLocal-分析-總結

系統 1576 0

原文地址: http://www.iteye.com/topic/777716

ThreadLocal<T>類在Spring,Hibernate等框架中起到了很大的作用,對于其工作原理,很多網上的文章分析的不夠徹底,甚至有些誤解。

?

首先,為了解釋ThreadLocal類的工作原理,必須同時介紹與其工作甚密的其他幾個類(內部類)

1.ThreadLocalMap

2.Thread

ThreadLocal-分析-總結

可能有人會覺得Thread與ThreadLocal有什么關系,其實真正的奧秘就在Thread類中的一行:

?

Java代碼 復制代碼 ? 收藏代碼
  1. ThreadLocal.ThreadLocalMap?threadLocals?=? null ;??

?其中ThreadLocalMap的定義是在ThreadLocal類中,真正的引用卻是在Thread類中

?

那么ThreadLocalMap究竟是什么呢?

?

可以看到這個類應該是一個Map,JDK的解釋是

?

?寫道
ThreadLocalMap is a customized hash map suitable only for maintaining thread local values

?

?

接下來的重點是ThreadLocalMap中用于存儲數據的entry

?

Java代碼 復制代碼 ? 收藏代碼
  1. static ? class ?Entry? extends ?WeakReference<ThreadLocal>?{ ??
  2. ???????????? /**?The?value?associated?with?this?ThreadLocal.?*/ ??
  3. ????????????Object?value; ??
  4. ??
  5. ????????????Entry(ThreadLocal?k,?Object?v)?{ ??
  6. ???????????????? super (k); ??
  7. ????????????????value?=?v; ??
  8. ????????????} ??
  9. ????????}??

?

?從中我們可以發現 這個Map的key是ThreadLocal變量,value為用戶的值,并不是網上大多數的列子key是線程的名字或者標識

?

到這里,我們就可以理解ThreadLocal究竟是如何工作的了

?

1.Thread類中有一個成員變量叫做ThreadLocalMap,它是一個Map,他的Key是ThreadLocal類

2 .每個線程擁有自己的申明為ThreadLocal類型的變量,所以這個類的名字叫'ThreadLocal':線程自己的(變量)

3.此變量生命周期是由該線程決定的,開始于第一次初始(get或者set方法)

4.由ThreadLocal的工作原理決定了: 每個線程獨自擁有一個變量,并非共享或者拷貝

?

Java代碼 復制代碼 ? 收藏代碼
  1. /** ?
  2. ?*?@author?mxdba ?
  3. ?* ?
  4. ?*/ ??
  5. public ? class ?ThreadLocalSample?{ ??
  6. ??
  7. ???? public ? static ? void ?main(String[]?args)?{ ??
  8. ????????ThreadTest?test1?=? new ?ThreadTest( 10 ); ??
  9. ????????ThreadTest?test2?=? new ?ThreadTest( 20 ); ??
  10. ????????test1.start(); ??
  11. ????????test2.start(); ??
  12. ????} ??
  13. ??
  14. } ??
  15. ??
  16. /** ?
  17. ?*?此線程有兩個ThreadLocal變量,但是由于ThreadLocal是延遲初始的, ?
  18. ?*?所以在debug時可以看到線程名為“線程20”的線程的ThreadLocalMap中沒有thLcal2這個entry ?
  19. ?*?@author?mxdba ?
  20. ?*? ?
  21. ?*/ ??
  22. class ?ThreadTest? extends ?Thread?{ ??
  23. ???? ??
  24. ???? public ? static ?ThreadLocal<Integer>?thLocal?=? new ?ThreadLocal<Integer>(); ??
  25. ???? public ? static ?ThreadLocal<String>?thLocal2?=? new ?ThreadLocal<String>(); ??
  26. ???? ??
  27. ???? public ?Integer?num; ??
  28. ???? ??
  29. ???? ??
  30. ???? ??
  31. ???? public ?ThreadTest(Integer?num)?{ ??
  32. ???????? super ( "線程" ?+?num); ??
  33. ???????? this .num?=?num; ??
  34. ????} ??
  35. ??
  36. ???? @Override ??
  37. ???? public ? void ?run()?{ ??
  38. ????????Integer?n?=?thLocal.get(); ??
  39. ???????? if (num?!=? 20 )?{ ??
  40. ????????????String?s?=?thLocal2.get(); ??
  41. ????????} ??
  42. ???????????? ??
  43. ???????? if (n?==? null )?{ ??
  44. ????????????thLocal.set(num); ??
  45. ????????} ??
  46. ????????System.out.println(thLocal.get()); ??
  47. ????} ??
  48. ???? ??
  49. }??

?

?

接下來分析一下源碼,就更加清楚了

?

關鍵方法代碼 復制代碼 ? 收藏代碼
  1. /** ??
  2. ?*?關鍵方法,返回當前Thread的ThreadLocalMap ??
  3. ?*?[[[每個Thread返回各自的ThreadLocalMap,所以各個線程中的ThreadLocal均為獨立的]]] ??
  4. ?*/ ??
  5. ThreadLocalMap?getMap(Thread?t)?{ ??
  6. ????????return?t.threadLocals; ??
  7. ????}??

?

?

?

?

Threadlocal的get方法代碼 復制代碼 ? 收藏代碼
  1. public?T?get()?{ ??
  2. ????????Thread?t?=?Thread.currentThread(); ??
  3. ????????/** ??
  4. ?????????*?得到當前線程的ThreadLocalMap ??
  5. ?????????*/ ??
  6. ????????ThreadLocalMap?map?=?getMap(t); ??
  7. ????????if?(map?!=?null)?{ ??
  8. ????????????/** ??
  9. ?????????????*?在此線程的ThreadLocalMap中查找key為當前ThreadLocal對象的entry ??
  10. ?????????????*/ ??
  11. ????????????ThreadLocalMap.Entry?e?=?map.getEntry(this); ??
  12. ????????????if?(e?!=?null) ??
  13. ????????????????return?(T)e.value; ??
  14. ????????} ??
  15. ????????return?setInitialValue(); ??
  16. ????}??

?

?

?

?

初始化方法代碼 復制代碼 ? 收藏代碼
  1. private?T?setInitialValue()?{ ??
  2. ????????/** ??
  3. ?????????*?默認返回null,這個方法為protected可以繼承 ??
  4. ?????????*/ ??
  5. ????????T?value?=?initialValue(); ??
  6. ????????Thread?t?=?Thread.currentThread(); ??
  7. ????????ThreadLocalMap?map?=?getMap(t); ??
  8. ????????if?(map?!=?null) ??
  9. ????????????map.set(this,?value); ??
  10. ????????else ??
  11. ????????????/** ??
  12. ?????????????*?初次創建 ??
  13. ?????????????*/ ??
  14. ????????????createMap(t,?value); ??
  15. ????????return?value; ??
  16. ????}??

?

?

?

Java代碼 復制代碼 ? 收藏代碼
  1. /** ?
  2. ?*?給當前thread初始ThreadlocalMap ?
  3. ?*/ ??
  4. void ?createMap(Thread?t,?T?firstValue)?{ ??
  5. ????????t.threadLocals?=? new ?ThreadLocalMap( this ,?firstValue); ??
  6. ????}??

?

?

?

通過上邊的分析,我們發現,ThreadLocal類的使用雖然是用來解決多線程的問題的,但是還是有很明顯的針對性

1. 最明顯的,ThreadLoacl變量的活動范圍為某線程,并且我的理解是該線程“專有的,獨自霸占”,對該變量的所有操作均有該線程完成! 也就是說,ThreadLocal不是用來解決共享,競爭問題的。典型的應用莫過于Spring,Hibernate等框架中對于多線程的處理了

?

Java代碼 復制代碼 ? 收藏代碼
  1. private ? static ? final ?ThreadLocal?threadSession?=? new ?ThreadLocal();?? ??
  2. ?? ??
  3. public ? static ?Session?getSession()? throws ?InfrastructureException?{?? ??
  4. ????Session?s?=?(Session)?threadSession.get();?? ??
  5. ???? try ?{?? ??
  6. ???????? if ?(s?==? null )?{?? ??
  7. ????????????s?=?getSessionFactory().openSession();?? ??
  8. ????????????threadSession.set(s);?? ??
  9. ????????}?? ??
  10. ????}? catch ?(HibernateException?ex)?{?? ??
  11. ???????? throw ? new ?InfrastructureException(ex);?? ??
  12. ????}?? ??
  13. ???? return ?s;?? ??
  14. }????

?這段代碼,每個線程有自己的ThreadLocalMap,每個ThreadLocalMap中根據需要初始加載threadSession,這樣的好處就是介于singleton與prototype之間,應用singleton無法解決線程,應用prototype開銷又太大,有了ThreadLocal之后就好了,對于需要線程“霸占”的變量用ThreadLocal,而該類實例的方法均可以共享。

?

2.關于內存泄漏:

雖然ThreadLocalMap已經使用了weakReference,但是還是建議能夠顯示的使用remove方法。

  • ThreadLocal-分析-總結
  • 大小: 9.9 KB
  • ThreadLocal-分析-總結
  • 大小: 13.9 KB

ThreadLocal-分析-總結


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 91色桃 | 亚洲日产综合欧美一区二区 | 狠狠综合久久综合网站 | 成人爱爱爱欧美日本视频 | 偷偷操99| 国产成人精品cao在线 | 香蕉免费一级视频在线观看 | 老子影院午夜久久亚洲 | 久久精品国产精品亚洲20 | 国内女高中生一级毛片 | 曰曰鲁夜夜免费播放视频 | 福利视频网页 | 亚洲欧美日韩国产精品影院 | 亚洲日本免费 | 狠狠色丁香久久婷婷综合_中 | 狠狠躁夜夜躁人人爽天天不 | 亚洲成人综合在线 | 国产一区国产二区国产三区 | 欧美精品久久久久久久久大尺度 | 日韩每日更新 | 日本我不卡 | 女性毛片 | 久久伊人影院 | 欧美在线一级精品 | 久久国产在线观看 | 久久婷婷色 | 欧美色综合高清免费 | 超清乱人伦中文视频在线 | 在线亚洲 欧美 日本专区 | 亚洲国产精 | 视频一区在线免费观看 | 在线观看av片永久免费 | 精品久久久久久久一区二区手机版 | 99视频都是精品热在线播放 | 国产成人久久 | 天天综合在线观看 | 免费视频福利 | 成人激情在线视频 | 亚洲久草 | 亚洲人xxx日本人18 | 四虎黄网|