0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

ThreadLocal是什么

jf_ro2CN3Fa ? 來(lái)源:CSDN ? 2023-01-30 11:36 ? 次閱讀


ThreadLocal是什么

ThreadLocal是一個(gè)本地線程副本變量工具類。主要用于將私有線程和該線程存放的副本對(duì)象做一個(gè)映射,各個(gè)線程之間的變量互不干擾,在高并發(fā)場(chǎng)景下,可以實(shí)現(xiàn)無(wú)狀態(tài)的調(diào)用,特別適用于各個(gè)線程依賴不通的變量值完成操作的場(chǎng)景。

下圖為ThreadLocal的內(nèi)部結(jié)構(gòu)圖

931b2958-9fb9-11ed-bfe3-dac502259ad0.png

從上面的結(jié)構(gòu)圖,我們已經(jīng)窺見(jiàn)ThreadLocal的核心機(jī)制:

  • 每個(gè)Thread線程內(nèi)部都有一個(gè)Map。
  • Map里面存儲(chǔ)線程本地對(duì)象(key)和線程的變量副本(value)
  • 但是,Thread內(nèi)部的Map是由ThreadLocal維護(hù)的,由ThreadLocal負(fù)責(zé)向map獲取和設(shè)置線程的變量值。

所以對(duì)于不同的線程,每次獲取副本值時(shí),別的線程并不能獲取到當(dāng)前線程的副本值,形成了副本的隔離,互不干擾。

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

ThreadLocalMap

932a8d58-9fb9-11ed-bfe3-dac502259ad0.png

ThreadLocalMap是ThreadLocal的內(nèi)部類,沒(méi)有實(shí)現(xiàn)Map接口,用獨(dú)立的方式實(shí)現(xiàn)了Map的功能,其內(nèi)部的Entry也獨(dú)立實(shí)現(xiàn)。

和HashMap的最大的不同在于,ThreadLocalMap結(jié)構(gòu)非常簡(jiǎn)單,沒(méi)有next引用,也就是說(shuō)ThreadLocalMap中解決Hash沖突的方式并非鏈表的方式,而是采用線性探測(cè)的方式。(ThreadLocalMap如何解決沖突?

在ThreadLocalMap中,也是用Entry來(lái)保存K-V結(jié)構(gòu)數(shù)據(jù)的。但是Entry中key只能是ThreadLocal對(duì)象,這點(diǎn)被Entry的構(gòu)造方法已經(jīng)限定死了。

staticclassEntryextendsWeakReference<ThreadLocal>{
/**ThevalueassociatedwiththisThreadLocal.*/
Objectvalue;

Entry(ThreadLocalk,Objectv){
super(k);
value=v;
}
}

注意了??!

Entry繼承自WeakReference(弱引用,生命周期只能存活到下次GC前),但只有Key是弱引用類型的,Value并非弱引用。(問(wèn)題馬上就來(lái)了)

由于ThreadLocalMap的key是弱引用,而Value是強(qiáng)引用。這就導(dǎo)致了一個(gè)問(wèn)題,ThreadLocal在沒(méi)有外部對(duì)象強(qiáng)引用時(shí),發(fā)生GC時(shí)弱引用Key會(huì)被回收,而Value不會(huì)回收。

當(dāng)線程沒(méi)有結(jié)束,但是ThreadLocal已經(jīng)被回收,則可能導(dǎo)致線程中存在ThreadLocalMap的鍵值對(duì),造成內(nèi)存泄露。(ThreadLocal被回收,ThreadLocal關(guān)聯(lián)的線程共享變量還存在)。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

如何避免泄漏

為了防止此類情況的出現(xiàn),我們有兩種手段。

1、使用完線程共享變量后,顯示調(diào)用ThreadLocalMap.remove方法清除線程共享變量;

既然Key是弱引用,那么我們要做的事,就是在調(diào)用ThreadLocal的get()set()方法時(shí)完成后再調(diào)用remove方法,將Entry節(jié)點(diǎn)和Map的引用關(guān)系移除,這樣整個(gè)Entry對(duì)象在GC Roots分析后就變成不可達(dá)了,下次GC的時(shí)候就可以被回收。

2、JDK建議ThreadLocal定義為private static,這樣ThreadLocal的弱引用問(wèn)題則不存在了。

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 變量
    +關(guān)注

    關(guān)注

    0

    文章

    614

    瀏覽量

    28827
  • 線程
    +關(guān)注

    關(guān)注

    0

    文章

    507

    瀏覽量

    20080
  • Thread
    +關(guān)注

    關(guān)注

    2

    文章

    88

    瀏覽量

    26385

原文標(biāo)題:ThreadLocal 搭配線程池使用造成內(nèi)存泄漏的原因和解決方案

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    DC紋波測(cè)試問(wèn)題

    為什么在測(cè)試DC紋波的時(shí)候,為什么有時(shí)候測(cè)出來(lái)是幾十mv,有時(shí)候測(cè)出來(lái)是20多V,是測(cè)試方法有問(wèn)題嗎,還是別的注意事項(xiàng),用的200M的帶寬
    發(fā)表于 06-08 22:00

    繼電器不能彈開是什么原因?想找?guī)煾到饣蟆?/a>

    我有幾十個(gè)取電開關(guān),都是繼電器不能彈開,導(dǎo)致開關(guān)不能正常使用。 單獨(dú)拆下繼電器,施加一個(gè)12伏電壓,繼電器正常能彈開。 我把4.000的晶振換新,以前有兩個(gè)開關(guān),換新晶振就沒(méi)問(wèn)題了,但是后面的幾十個(gè),換新晶振也沒(méi)用,檢查其他零件,沒(méi)發(fā)現(xiàn)問(wèn)題。 所以,想請(qǐng)教師傅們,這個(gè)問(wèn)題需要怎么解決才能讓繼電器恢復(fù)彈開?
    發(fā)表于 06-08 19:37

    Analog Devices Inc. ADL8141低噪聲放大器數(shù)據(jù)手冊(cè)

    Analog Devices Inc. ADL8141低噪聲放大器設(shè)計(jì)用于14GHz至24GHz的運(yùn)行。Analog Devices Inc. ADL8141具有29dB的典型增益、1.4dB的噪聲系數(shù)、18dBm的輸出三階交調(diào)截點(diǎn) (OIP3)。由2V電源提供25mA的典型供電電流,對(duì)連接到RBIAS引腳的電源參考電阻器進(jìn)行調(diào)節(jié),可以增強(qiáng)OIP3和1dB壓縮點(diǎn) (OP1dB) 的輸出功率。RF輸入和輸出是內(nèi)部匹配的交流耦合的。
    的頭像 發(fā)表于 06-08 17:52 ?67次閱讀
    Analog Devices Inc. ADL8141低噪聲放大器數(shù)據(jù)手冊(cè)

    Analog Devices Inc. EVAL-ADL8100 評(píng)估板數(shù)據(jù)手冊(cè)

    Analog Devices Inc. EVAL-ADL8100評(píng)估板采用由10mil厚Rogers 4350B銅覆板制成的2層PCB,PCB安裝在鋁散熱片上。該散熱片為PCB提供散熱和機(jī)械支撐。安裝孔方便連接到較大散熱器,實(shí)現(xiàn)更好的熱管理。Analog Devices ADL8100ACPZN-EVALZ和ADL8100ACPZN-EVAL1Z具有RFIN和RFOUT端口,帶2.9mm母頭同軸連接器。相應(yīng)的RF走線保持50Ω 的特性阻抗。這些電路板采用適合-40°C至+85°C工作溫度范圍的元件。
    的頭像 發(fā)表于 06-08 17:43 ?64次閱讀

    【RA4L1-SENSOR】電壓表 - 段碼LCD顯示屏

    瑞薩 R7FA4L1BD4CFP 內(nèi)置 LCD 驅(qū)動(dòng)器 Segment LCD Controller(SLCDC),可直接驅(qū)動(dòng) 靜態(tài)、1/2、1/3、1/4 Bias 的段式 LCD 顯示屏,無(wú)需額外的 LCD 驅(qū)動(dòng)芯片。 RA4L1 還內(nèi)置 12bit ADC,可以采樣外部電壓和芯片內(nèi)部溫度傳感器模擬電壓 使能 ADC 和 SLCDC 模塊,可以將 ADC 采集的電壓值顯示到液晶顯示屏上,如下: RA4L1 板載 LCD 段碼屏,結(jié)構(gòu)如下: 電路連接如下: SLCDC 控制器配置可以參考如下文章: https://coremaker.blog.csdn.net/article/details/146589863 https://coremaker.blog.csdn.net/article/details/146590286 配置好 SLCDC 后,再配置 ADC 單次觸發(fā)采樣,使能 ADC 轉(zhuǎn)換完成中斷: ADC 轉(zhuǎn)換寫成函數(shù),代碼如下,可以直接調(diào)用: void ADC0_Init(void) { fsp_err_t err; /* Initializes the module. */ err = R_ADC_Open(&g_adc0_ctrl, &g_adc0_cfg); /* Handle any errors. This function should be defined by the user. */ assert(FSP_SUCCESS == err); /* Enable channels. */ err = R_ADC_ScanCfg(&g_adc0_ctrl, &g_adc0_channel_cfg); assert(FSP_SUCCESS == err); } void ADC0_Convert(u8 channel) { fsp_err_t err; FSP_PARAMETER_NOT_USED(channel); /* Enable scan triggering from ELC events. */ R_ADC_ScanStart(&g_adc0_ctrl); } u16 ADC0_GetValue(u8 channel) { fsp_err_t err; u16 ret; err = R_ADC_Read(&g_adc0_ctrl, (adc_channel_t)channel, &ret); assert(FSP_SUCCESS == err); return ret; } 最終代碼調(diào)用如下: int my_main(void) { u16 adc; fsp_err_t err; GPIO_PIN_H(GPIO6, 1); GPIO_PIN_H(GPIO6, 9); GPIO_PIN_H(GPIO6, 10); Delay_Ms(1000); SLCDC_Init(); ADC0_Init(); ADC0_Convert(25); while (1) { if (scan_complete_flag) { adc = ADC0_GetValue(25); SLCDC_Voltage((u32)adc*330/4095); scan_complete_flag = false; ADC0_Convert(25); Delay_Ms(100); } } return 0; }
    發(fā)表于 06-08 17:40

    Analog Devices Inc. ADPA9007 2W功率放大器數(shù)據(jù)手冊(cè)

    Analog Devices Inc. ADPA9007 2W功率放大器 工作在直流至28GHz的頻率范圍內(nèi),具有 內(nèi)部匹配的直流耦合的RF輸入和輸出。Analog Devices Inc. ADPA9007具有集成的溫度補(bǔ)償?shù)腞F功率檢測(cè)器和內(nèi)置的溫度傳感器。從2GHz至16GHz,該放大器具有12.5dB的增益、33dBm的OP1dB、45dBm的OIP3,工作在15V典型值的電源電壓上,具有500mA可調(diào)節(jié)的偏置電流。
    的頭像 發(fā)表于 06-08 17:37 ?62次閱讀
    Analog Devices Inc. ADPA9007 2W功率放大器數(shù)據(jù)手冊(cè)

    TPS629206 采用 SOT-583 封裝的 3V 至 17V、0.6A、低 IQ 同步降壓轉(zhuǎn)換器數(shù)據(jù)手冊(cè)

    TPS6292xx 系列器件是高效、小型且高度靈活的同步降壓直流/直流轉(zhuǎn)換器,易于使用。3V 至 1 7V 的寬輸入電壓范圍支持由 12V、5V 或 3.3V 電源軌或單節(jié)或多節(jié)鋰離子電池供電的各種系統(tǒng)。TPS629206 可配置為在強(qiáng)制 PWM 模式或可變頻率(自動(dòng) PFM)模式下以 2.5 MHz 或 1 MHz 運(yùn)行。在自動(dòng) PFM 模式下,該器件在輕負(fù)載時(shí)自動(dòng)轉(zhuǎn)換至省電模式,以保持高效率。4μA 的典型低靜態(tài)電流還可以在最小負(fù)載下提供高效率。
    的頭像 發(fā)表于 06-08 17:22 ?186次閱讀
    TPS629206 采用 SOT-583 封裝的 3V 至 17V、0.6A、低 IQ 同步降壓轉(zhuǎn)換器數(shù)據(jù)手冊(cè)

    TPS629211-Q1 采用 SOT-583 封裝的汽車類 3V 至 10V、1A、高效率、低 IQ 同步降壓轉(zhuǎn)換器數(shù)據(jù)手冊(cè)

    TPS629211-Q1是一款專為汽車應(yīng)用設(shè)計(jì)的1A同步降壓DC-DC轉(zhuǎn)換器,支持3V至10V的寬輸入電壓范圍。該器件符合AEC-Q100標(biāo)準(zhǔn),具有高效能、小尺寸和高度靈活性等特點(diǎn),適用于高級(jí)駕駛輔助系統(tǒng)(ADAS)、汽車信息娛樂(lè)和儀表集群、車身電子和照明系統(tǒng)等應(yīng)用。
    的頭像 發(fā)表于 06-08 17:03 ?155次閱讀
    TPS629211-Q1 采用 SOT-583 封裝的汽車類 3V 至 10V、1A、高效率、低 IQ 同步降壓轉(zhuǎn)換器數(shù)據(jù)手冊(cè)

    TPS629210E 3V 至 17V、1A、高效同步降壓轉(zhuǎn)換器,溫度范圍為 -55°C 至 150°C數(shù)據(jù)手冊(cè)

    TPS629210E 器件是一款高效、小型、高度靈活的同步整流降壓 DC-DC 轉(zhuǎn)換器,易于使用。3V 至 1 7V 的寬輸入電壓范圍支持由 12V、5V 或 3.3V 電源軌或單節(jié)或多節(jié)鋰離子電池供電的各種系統(tǒng)。TPS629210E 可配置為在強(qiáng)制 PWM 模式或可變頻率(自動(dòng) PFM)模式下以 2.5 MHz 或 1 MHz 運(yùn)行。在自動(dòng) PFM 模式下,該器件在輕負(fù)載時(shí)自動(dòng)轉(zhuǎn)換至省電模式,以保持高效率。4μA 的典型低靜態(tài)電流還可以在最小負(fù)載下提供高效率。TI 的自動(dòng)效率增強(qiáng) (AEE) 模式可根據(jù)輸入和輸出電壓自動(dòng)調(diào)整開關(guān)頻率,從而在整個(gè)工作范圍內(nèi)保持高轉(zhuǎn)換效率,而無(wú)需使用不同的電感器。
    的頭像 發(fā)表于 06-08 16:42 ?170次閱讀
    TPS629210E 3V 至 17V、1A、高效同步降壓轉(zhuǎn)換器,溫度范圍為 -55°C 至 150°C數(shù)據(jù)手冊(cè)

    【正點(diǎn)原子STM32MP257開發(fā)板試用】智能門鎖

    前言 感謝正點(diǎn)原子和電子發(fā)燒友論壇提供的這次機(jī)會(huì)讓我有機(jī)會(huì)體驗(yàn)這款正點(diǎn)原子STM32MP257開發(fā)板,希望可以借這個(gè)機(jī)會(huì)好好學(xué)習(xí)一下。 開箱 箱子還是那個(gè)黑箱子: 沒(méi)有想到還配送了一個(gè)MIPI的屏幕,開發(fā)板組裝好長(zhǎng)這樣(屏幕本身就好了,天線要自己裝): 燒錄系統(tǒng) 打開鏈接: https://pan.baidu.com/s/1YsU7Tca8cQ85xrV4WhZPpA 提取碼: d6u9 進(jìn)入08.系統(tǒng)鏡像,將底下的文件全部下載下來(lái): 將USB線插入U(xiǎn)SB-OTG,把撥碼開關(guān)調(diào)為0000:打開STM32的下載軟件STM32CubeProgrammer,按照下方的方法配置,并點(diǎn)擊Download即可: 下載完后就可以將撥碼開關(guān)調(diào)回0100,上電打開串口,在設(shè)備樹配置中選擇3(根據(jù)屏幕自行選擇): 這時(shí)就可以看到屏幕亮了起來(lái),過(guò)了一會(huì)兒就進(jìn)入了系統(tǒng): 配置系統(tǒng) 進(jìn)入系統(tǒng)后,發(fā)現(xiàn)時(shí)間很明顯有問(wèn)題,所以我們可以在shell中使用: timedatectl set-timezone \'Etc/GMT-8\' 這樣就解決了時(shí)間問(wèn)題。 目前只有這個(gè)問(wèn)題,接著就可以自行體驗(yàn)了。
    發(fā)表于 06-08 16:03

    TPS629206-Q1 采用 SOT-583 封裝的汽車類 3V 至 17V、0.6A、低 IQ 同步降壓轉(zhuǎn)換器數(shù)據(jù)手冊(cè)

    符合汽車標(biāo)準(zhǔn)的 TPS6292xx -Q1 系列器件是高效、小型、高度靈活的同步降壓直流/直流轉(zhuǎn)換器,易于使用。3V 至 1 7V 的寬輸入電壓范圍支持由 12V、5V 或 3.3V 電源軌或單節(jié)或多節(jié)鋰離子電池供電的各種系統(tǒng)。TPS629206-Q1 可配置為在強(qiáng)制 PWM 模式或可變頻率(自動(dòng) PFM)模式下以 2.5 MHz 或 1 MHz 運(yùn)行。在自動(dòng) PFM 模式下,該器件在輕負(fù)載時(shí)自動(dòng)轉(zhuǎn)換至省電模式,以保持高效率。4μA 的典型低靜態(tài)電流還可以在最小負(fù)載下提供高效率。
    的頭像 發(fā)表于 06-08 15:57 ?163次閱讀
    TPS629206-Q1 采用 SOT-583 封裝的汽車類 3V 至 17V、0.6A、低 IQ 同步降壓轉(zhuǎn)換器數(shù)據(jù)手冊(cè)

    TPS62A01 2.5V 至 5.5V 輸入、1A 輸出高效降壓轉(zhuǎn)換器數(shù)據(jù)手冊(cè)

    TPS62A0x 系列器件是同步降壓直流/直流轉(zhuǎn)換器,針對(duì)高效率和緊湊設(shè)計(jì)尺寸進(jìn)行了優(yōu)化。這些器件集成了能夠提供高達(dá) 2A 輸出電流的開關(guān)。在中到重負(fù)載下,這些器件以 2.4MHz 開關(guān)頻率的脈寬調(diào)制 (PWM) 模式運(yùn)行。在輕負(fù)載時(shí),這些器件會(huì)自動(dòng)進(jìn)入省電模式 (PSM),以在整個(gè)負(fù)載電流范圍內(nèi)保持高效率。在停機(jī)模式下,電流消耗也是最小的。該器件系列的 TPS62A0xA 變體在整個(gè)負(fù)載電流范圍內(nèi)以強(qiáng)制 PWM 運(yùn)行。
    的頭像 發(fā)表于 06-08 15:37 ?176次閱讀
    TPS62A01 2.5V 至 5.5V 輸入、1A 輸出高效降壓轉(zhuǎn)換器數(shù)據(jù)手冊(cè)

    LMR43610-Q1 具有低 IQ 的汽車類 3V 至 36V、1A、低 EMI 同步降壓穩(wěn)壓器數(shù)據(jù)手冊(cè)

    LMR436x0-Q1 是業(yè)界最小的 36V、2A 和 1A 同步降壓直流/直流轉(zhuǎn)換器,采用 2mm × 2mm HotRod 封裝。這款易于使用的轉(zhuǎn)換器支持 3.0V 至 36V 的寬輸入電壓范圍,瞬態(tài)電壓高達(dá) 42V。 LMR43620-Q1 專為滿足始終開啟的汽車應(yīng)用的低待機(jī)功率要求而設(shè)計(jì)。自動(dòng)模式在輕負(fù)載下運(yùn)行時(shí)啟用頻率折返,允許在 13.5VIN 下實(shí)現(xiàn) 1.5μA 的空載電流消耗和高輕負(fù)載效率。PWM 和 PFM 模式之間的無(wú)縫轉(zhuǎn)換以及極低的 MOSFET 導(dǎo)通電阻可在整個(gè)負(fù)載范圍內(nèi)提供卓越的效率。
    的頭像 發(fā)表于 06-08 15:18 ?164次閱讀
    LMR43610-Q1 具有低 IQ 的汽車類 3V 至 36V、1A、低 EMI 同步降壓穩(wěn)壓器數(shù)據(jù)手冊(cè)

    Kuikly鴻蒙版正式開源 —— 揭秘卓越性能適配之旅

    進(jìn)行評(píng)測(cè)對(duì)比,發(fā)現(xiàn)鴻蒙上的耗時(shí)是同等性能的iOS設(shè)備上2.48倍。為此,我們針對(duì)鴻蒙平臺(tái)進(jìn)行一系列的優(yōu)化,包括內(nèi)聯(lián)優(yōu)化、ThreadLocal優(yōu)化、協(xié)程性能優(yōu)化等。優(yōu)化后,鴻蒙Kotlin
    發(fā)表于 06-04 16:46

    電子發(fā)燒友

    中國(guó)電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會(huì)員交流學(xué)習(xí)
    • 獲取您個(gè)性化的科技前沿技術(shù)信息
    • 參加活動(dòng)獲取豐厚的禮品