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

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

ThreadLocal-分析-總結(jié)

系統(tǒng) 1653 0

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

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

?

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

1.ThreadLocalMap

2.Thread

ThreadLocal-分析-總結(jié)

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

?

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

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

?

那么ThreadLocalMap究竟是什么呢?

?

可以看到這個類應(yīng)該是一個Map,JDK的解釋是

?

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

?

?

接下來的重點是ThreadLocalMap中用于存儲數(shù)據(jù)的entry

?

Java代碼 復(fù)制代碼 ? 收藏代碼
  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. ????????}??

?

?從中我們可以發(fā)現(xiàn) 這個Map的key是ThreadLocal變量,value為用戶的值,并不是網(wǎng)上大多數(shù)的列子key是線程的名字或者標識

?

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

?

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

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

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

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

?

Java代碼 復(fù)制代碼 ? 收藏代碼
  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. }??

?

?

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

?

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

?

?

?

?

Threadlocal的get方法代碼 復(fù)制代碼 ? 收藏代碼
  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. ????}??

?

?

?

?

初始化方法代碼 復(fù)制代碼 ? 收藏代碼
  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. ?????????????*?初次創(chuàng)建 ??
  13. ?????????????*/ ??
  14. ????????????createMap(t,?value); ??
  15. ????????return?value; ??
  16. ????}??

?

?

?

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

?

?

?

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

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

?

Java代碼 復(fù)制代碼 ? 收藏代碼
  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中根據(jù)需要初始加載threadSession,這樣的好處就是介于singleton與prototype之間,應(yīng)用singleton無法解決線程,應(yīng)用prototype開銷又太大,有了ThreadLocal之后就好了,對于需要線程“霸占”的變量用ThreadLocal,而該類實例的方法均可以共享。

?

2.關(guān)于內(nèi)存泄漏:

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

  • ThreadLocal-分析-總結(jié)
  • 大小: 9.9 KB
  • ThreadLocal-分析-總結(jié)
  • 大小: 13.9 KB

ThreadLocal-分析-總結(jié)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 奇米狠狠操 | 99热在线国产| 免费观看性欧美一级 | 国产午夜精品一区二区三区在线观看 | 国产福利免费在线观看 | 国产福利区一区二在线观看 | 在线观看日韩 | 天天爽夜夜爽夜夜爽 | www.亚洲黄色 | 国产成人精品一区二区三区电影 | 亚洲欧美日韩国产精品26u | 无码人妻精品1国产婷婷 | 欧美一区二区三区视频 | 国产理论自拍 | 亚州人成网在线播放 | 国产精品亚洲视频 | 九九视频九九热 | 久久一日本道色综合久久m 亚洲三级视频 | 亚州人成网在线播放 | 黑色丝袜三级在线播放 | 国产大片在线观看 | 日韩三级免费观看 | 欧美日韩视频一区三区二区 | 亚洲午夜日韩高清一区 | 一区二区三区视频 | 国产精品爱久久久久久久 | 国产色 | 日韩精品hd | 538在线精品 | 夜班护士在线观看 | jizzjizzjizz亚洲女| 久草2018| 两性免费视频 | 欧美一级片在线看 | 国产喷水 | 91欧美精品激情在线观看 | 久久影音先锋 | 99久久久无码国产精品 | 国产精品啪一品二区三区粉嫩 | 91久久精品国产一区二区 | 男生日女生免费视频 |