Java中的線程ThreadLocal詳細(xì)解析
一 Java中的引用關(guān)系
Java中的引用分為了強(qiáng)引用、弱引用、軟引用、虛引用
- 強(qiáng)引用: 垃圾回收的時(shí)候,如果內(nèi)存不足也不會(huì)進(jìn)行垃圾回收,會(huì)報(bào)out-of-memory異常
- 弱引用: 垃圾回收的時(shí)候,如果內(nèi)存不夠,則數(shù)據(jù)被回收.
- 軟引用: 垃圾回收的時(shí)候,軟引用會(huì)立刻進(jìn)行回收
- 虛引用: 垃圾回收的時(shí)候,軟引用會(huì)立刻進(jìn)行回收
二 ThreadLocal代碼實(shí)現(xiàn)
ThreadLocal是線程本地變量,存儲(chǔ)在ThreadLocal里面的數(shù)據(jù)都是 線程安全的.
一般ThreadLocal適用的場(chǎng)景多是各個(gè)線程間沒有變量共享需要的同步問題場(chǎng)景,比如一個(gè)簡(jiǎn)單的SimpleDateFormat類,該類不是線程安全的,卻是有狀態(tài)的,如果將SimpleDateFormat設(shè)置為靜態(tài)的,所有線程共享,那么就會(huì)出現(xiàn)線程安全的問題,其中一個(gè)線程修改日期格式為“yyyyMMdd”,然后可能會(huì)影響到另外一個(gè)需要格式為“yyyy-MM-dd”的線程。但是如果在方法中每次用到的時(shí)候都new一個(gè)SimpleDateFormat類又太費(fèi)內(nèi)存(SimpleDateFormat這種簡(jiǎn)單的類倒還好,若是一些比較占用資源的比如數(shù)據(jù)庫(kù)連接類等,就會(huì)讓加大整個(gè)數(shù)據(jù)庫(kù)的壓力),這時(shí)候采用ThreadLocal為每一個(gè)線程保存一份SimpleDateFormat副本,這樣既不會(huì)說每次調(diào)用方法都會(huì)生成一個(gè)對(duì)象,也不會(huì)在并發(fā)時(shí)產(chǎn)生線程同步問題。這就像是在共享一個(gè)靜態(tài)變量和每次使用都new一個(gè)對(duì)象兩者之間的一種折中處理方法。
自己實(shí)現(xiàn)的ThreadLocal

通過一個(gè)全局map, key是Thread對(duì)象,value是對(duì)應(yīng)存儲(chǔ)的數(shù)據(jù),這種情況下 如果map不銷毀,對(duì)應(yīng)的Thread線程就不發(fā)被回收,導(dǎo)致內(nèi)存泄露
JDK中使用的ThreadLocal

JDK8中在Thread對(duì)象中引用ThreadLocalMap,ThreadLocalMap的生命周期是Thread是同一個(gè)生命周期.
ThreadLocalMap的實(shí)現(xiàn)
(1) Entry數(shù)組實(shí)現(xiàn)

Entry數(shù)組是線程中實(shí)際存放數(shù)據(jù)的地方,key是ThreadLocal,是一個(gè)弱引用,value是對(duì)應(yīng)存儲(chǔ)的值.
為什么ThreadLocalMap#key是一個(gè)弱引用
如果外部不使用了ThreadLocal,則對(duì)應(yīng)的數(shù)據(jù)不應(yīng)該存儲(chǔ)在ThreadLocal中,應(yīng)該被刪除掉,防止內(nèi)存泄漏
ThreadLocalMap的屬性
private static final int INITIAL_CAPACITY = 16;
//存儲(chǔ)數(shù)據(jù)的地方
private Entry[] table; //
//數(shù)量
private int size = 0;
private int threshold; // Default to 0
ThreadLocal的方法
ThreadLocal#set()方法

(1) 第一步 獲取到當(dāng)前線程的ThreadLocalMap
(2) 第二步 初始化ThreadLocalMap
(3) 第三步 將ThreadLocal作為key,value值作為值,設(shè)置到map中
ThreadLocal # get()方法

方法主要完成兩個(gè)功能: (1) 完成數(shù)據(jù)的讀取 (2) 將ThreadLocalMap中key為NULL的數(shù)據(jù)從ThreadLocalMap中刪除
ThreadLocalMap中的entry其實(shí)是繼承的弱引用,如果該弱引用指向的ThreadLocal沒有在外部被強(qiáng)引用指向的話,在下次gc的時(shí)候就會(huì)被回收,那這樣的話就會(huì)出現(xiàn)ThreadLocalMap中存在key為null的情況,這樣的數(shù)據(jù)對(duì)于map來講是臟數(shù)據(jù),這樣的臟數(shù)據(jù)沒有用,卻一直占用著map的存儲(chǔ)空間,這其實(shí)就是一種內(nèi)存泄漏,所以需要來釋放掉這些空間
三 ThreadLocalMap的內(nèi)存泄漏問題
如果ThreadLocal無(wú)強(qiáng)引用進(jìn)行應(yīng)用,則在垃圾回收的時(shí)候會(huì)把這個(gè)key進(jìn)行回收.
這個(gè)時(shí)候,因?yàn)榫€程還存活,所以ThreadLocalMap依舊存在,但是key為null,這個(gè) key對(duì)應(yīng)的value就無(wú)法被訪問到了,造成內(nèi)存泄漏.
JDK團(tuán)隊(duì)自己的解決辦法
調(diào)用get()、set()方法的時(shí)候,自動(dòng)清理掉ThreadLocalMap中key為null的數(shù)據(jù)
開發(fā)者的解決辦法 使用ThreadLocal后,調(diào)用ThreadLocal
到此這篇關(guān)于Java中的線程ThreadLocal詳細(xì)解析的文章就介紹到這了,更多相關(guān)Java的ThreadLocal內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot+thymeleaf+Echarts+Mysql 實(shí)現(xiàn)數(shù)據(jù)可視化讀取的示例
本文主要介紹了SpringBoot+thymeleaf+Echarts+Mysql 實(shí)現(xiàn)數(shù)據(jù)可視化讀取的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
java中給實(shí)體對(duì)象屬性的空值賦默認(rèn)值
這篇文章主要介紹了java中給實(shí)體對(duì)象屬性的空值賦默認(rèn)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
HDFS?Balancer負(fù)載均衡器及語(yǔ)法詳解
這篇文章主要為大家介紹了HDFS?Balancer負(fù)載均衡器及語(yǔ)法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
JAVA 截取字符串的三種方法 subString,StringUtils,split實(shí)例詳解
這篇文章給大家介紹JAVA 截取字符串的三種方法 subString,StringUtils,split,每種方法結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-12-12
完美解決springboot中使用mybatis字段不能進(jìn)行自動(dòng)映射的問題
今天在springboot中使用mybatis的時(shí)候不能字段不能夠進(jìn)行自動(dòng)映射,接下來給大家給帶來了完美解決springboot中使用mybatis字段不能進(jìn)行自動(dòng)映射的問題,需要的朋友可以參考下2023-05-05
SpringBoot中注解@ConfigurationProperties與@Value的區(qū)別與使用詳解
本文主要介紹了SpringBoot中注解@ConfigurationProperties與@Value的區(qū)別與使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
SpringBoot實(shí)現(xiàn)IP地址解析的示例代碼
本篇帶大家實(shí)踐在springboot項(xiàng)目中獲取請(qǐng)求的ip與詳細(xì)地址,我們的很多網(wǎng)站app中都已經(jīng)新增了ip地址顯示,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
java如何不通過構(gòu)造函數(shù)創(chuàng)建對(duì)象(Unsafe)
這篇文章主要介紹了java如何不通過構(gòu)造函數(shù)創(chuàng)建對(duì)象(Unsafe)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03

