色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

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

ThreadLocal的短板,我TTL來補(bǔ)!

jf_ro2CN3Fa ? 來源:芋道源碼 ? 2023-09-27 16:22 ? 次閱讀


有小伙伴讓我再說說TransmittableThreadLocal(下邊統(tǒng)一簡(jiǎn)稱:TTL),它是阿里開源的一個(gè)工具類,解決異步執(zhí)行時(shí)上下文傳遞的問題。

那今天就來介紹介紹 TTL,補(bǔ)充下 ThreadLocal 家族的短板吧。

這篇過后,ThreadLocal 就真的一網(wǎng)打盡了!

不過還是建議先看看前置篇(文末會(huì)放鏈接),不然理解起來可能有點(diǎn)困難。

緣由

任何一個(gè)組件的出現(xiàn)必有其緣由,知其緣由背景才能更深刻地理解它。

我們知道 ThreadLocal 的出現(xiàn)就是為了本地化線程資源,防止不必要的多線程之間的競(jìng)爭(zhēng)。

在有些場(chǎng)景,當(dāng)父線程 new 一個(gè)子線程的時(shí)候,希望把它的 ThreadLocal 繼承給子線程。

這時(shí)候 InheritableThreadLocal 就來了,它就是為了父子線程傳遞本地化資源而提出的。

具體的實(shí)現(xiàn)是在子線程對(duì)象被 new 的時(shí)候,即 Thread.init 的時(shí),如果查看到父線程內(nèi)部有 InheritableThreadLocal 的數(shù)據(jù)。

那就在子 Thread 初始化的時(shí),把父線程的 InheritableThreadLocal 拷貝給子線程。

141edfde-5cd6-11ee-939d-92fbcf53809c.png

就這樣簡(jiǎn)單地把父線程的 ThreadLocal 數(shù)據(jù)傳遞給子線程了。

但是,這個(gè)場(chǎng)景只能發(fā)生在 new Thread 的時(shí)候!也就是手動(dòng)創(chuàng)建線程之時(shí)!那就有個(gè)問題了,在平時(shí)我們使用的時(shí)候基本用的都是線程池。

那就麻了啊,線程池里面的線程都預(yù)創(chuàng)建好了,調(diào)用的時(shí)候就沒法直接用 InheritableThreadLocal 了。

所以就產(chǎn)生了一個(gè)需求,如何往線程池內(nèi)的線程傳遞 ThreadLocal?,JDK 的類庫(kù)沒這個(gè)功能,所以怎么搞?

只能我們自己造輪子了。

基于 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/

如何設(shè)計(jì)?

需求已經(jīng)明確了,但是怎么實(shí)現(xiàn)呢?

平時(shí)我們用線程池的話,比如你要提交任務(wù),則使用代碼如下:

Runnabletask=newRunnable....;
executorService.submit(task);

小貼士:以下的 ThreadLocal 泛指線程本地?cái)?shù)據(jù),不是指 ThreadLocal 這個(gè)類

這時(shí)候,我們想著把當(dāng)前線程的 ThreadLocal 傳遞給線程池內(nèi)部將要執(zhí)行這個(gè) task 的線程。

但此時(shí)我們哪知道線程池里面的哪個(gè)線程會(huì)來執(zhí)行這個(gè)任務(wù)?

所以,我們得先把當(dāng)前線程的 ThreadLocal 保存到這個(gè) task 中。

然后當(dāng)線程池里的某個(gè)線程,比如線程 A 獲取這個(gè)任務(wù)要執(zhí)行的時(shí)候,看看 task 里面是否有存儲(chǔ)著的 ThreadLocal 。

如果存著那就把這個(gè) ThreadLocal 放到線程 A 的本地變量里,這樣就完成了傳遞。

然后還有一步,也挺關(guān)鍵的,就是恢復(fù)線程池內(nèi)部執(zhí)行線程的上下文,也就是該任務(wù)執(zhí)行完畢之后,把任務(wù)帶來的本地?cái)?shù)據(jù)給刪了,把線程以前的本地?cái)?shù)據(jù)復(fù)原。

143073d4-5cd6-11ee-939d-92fbcf53809c.png

設(shè)計(jì)思路應(yīng)該已經(jīng)很明確了吧?來看看具體需要如何實(shí)現(xià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/

如何實(shí)現(xiàn)?

把上面的設(shè)計(jì)簡(jiǎn)單地、直白地翻譯成代碼如下:

1446c508-5cd6-11ee-939d-92fbcf53809c.png

如果你讀過我之前分析 ThreadLocal 的文章,應(yīng)該可以很容易的理解上面的操作。

這樣雖然可以實(shí)現(xiàn),但是可操作性太差,耦合性太高。

所以我們得想想怎么優(yōu)化一下,其實(shí)有個(gè)設(shè)計(jì)模式就很合適,那就是裝飾器模式。

我們可以自己搞一個(gè) Runnable 類,比如 YesRunnable,然后在 new YesRunnable 的時(shí)候,在構(gòu)造器里面把當(dāng)前線程的 threadlocal 賦值進(jìn)去。

然后 run 方法那里也修飾一下,我們直接看看偽代碼:

publicYesRunnable(Runnablerunable){
this.threadlocalCopy=copyFatherThreadlocal();
this.runable=runable;
}
publicvoidrun(){
//塞入父threadlocal,并返回當(dāng)前線程原先threadlocal
 Object backup = setThreadlocal(threadlocalCopy);
try{
 runable.run();//執(zhí)行被裝飾的任務(wù)邏輯
}finally{
restore(backup);//復(fù)原當(dāng)前線程的上下文
}
}

使用方式如下:

Runnabletask=()->{...};
YesRunnableyesRunnable=newYesRunnable(task);
executorService.submit(yesRunnable);

你看,這不就實(shí)現(xiàn)我們上面的設(shè)計(jì)了嘛!

不過還有一個(gè)點(diǎn)沒有揭秘,就是如何實(shí)現(xiàn) copyFatherThreadlocal

我們?nèi)绾蔚弥妇€程現(xiàn)在到底有哪些 Threadlocal?并且哪些是需要上下文傳遞的?

所以我們還需要?jiǎng)?chuàng)建一個(gè)類來繼承 Threadlocal。

比如叫 YesThreadlocal,用它聲明的變量就表明需要父子傳遞的!

publicclassYesThreadlocal<T>extendsThreadLocal<T>

然后我們需要搞個(gè)地方來存儲(chǔ)當(dāng)前父線程上下文用到的所有 YesThreadlocal,這樣在 copyFatherThreadlocal的時(shí)候我們才好遍歷復(fù)制對(duì)吧?

我們可以搞個(gè) holder 來保存這些 YesThreadlocal ,不過 holder 變量也得線程隔離。

畢竟每個(gè)線程所要使用的 YesThreadlocal 都不一樣,所以需要用 ThreadLocal 來修飾 holder 。

然后 YesThreadlocal 可能會(huì)有很多,我們可以用 set 來保存。

但是為了防止我們搞的這個(gè) holder 造成內(nèi)存泄漏的風(fēng)險(xiǎn),我們需要弱引用它,不過沒有 WeakHashSet,那我們就用 WeakHashMap 來替代存儲(chǔ)。

privatestaticfinalThreadLocal,?>>holder=new.....

這樣我們就打造了一個(gè)變量,它是線程獨(dú)有的,且又能拿來存儲(chǔ)當(dāng)前線程用到的所有 YesThreadLocal ,便于后面的復(fù)制,且又不會(huì)造成內(nèi)存泄漏(弱引用)。

是不是感覺有點(diǎn)暫時(shí)理不清?沒事,我們繼續(xù)來看看具體怎么用上這個(gè) hold ,可能會(huì)清晰些。

首先我們將需要傳遞給線程池的本地變量從 ThreadLocal 替換成 YesThreadLocal。

然后重寫 set 方法,實(shí)現(xiàn)如下:

@Override
publicfinalvoidset(Tvalue){
super.set(value);//調(diào)用ThreadLocal的set
addThisToHolder();//把當(dāng)前的 YesThreadLocal 對(duì)象塞入 hold 中。
}
privatevoidaddThisToHolder(){
if(!holder.get().containsKey(this)){
holder.get().put((YesThreadLocal)this,null);
}
}

			

你看這樣就把所有用到的 YesThreadLocal 塞到 holder 中了,然后再來看看 copyFatherThreadlocal 應(yīng)該如何實(shí)現(xiàn)。

privatestaticHashMap,Object>copyFatherThreadlocal(){
HashMap,Object>fatherMap=newHashMap,Object>();
for(YesThreadLocalthreadLocal:YesThreadLocal.holder.get().keySet()){
fatherMap.put(threadLocal,threadLocal.copyValue());
}
returnfatherMap;
}

			

邏輯很簡(jiǎn)單,就是一個(gè) map 遍歷拷貝。

我現(xiàn)在用一段話來小結(jié)一下,把上面的全部操作聯(lián)合起來理解,應(yīng)該會(huì)清晰很多。

實(shí)現(xiàn)思路小結(jié)

1.新建一個(gè) YesThreadLocal 類繼承自 ThreadLocal ,用于標(biāo)識(shí)這個(gè)修飾的變量需要父子線程拷貝

2.新建一個(gè) YesRunnable 類繼承自 Runnable,采用裝飾器模式,這樣就不用修改原有的 Runnable。在構(gòu)造階段復(fù)制父線程的 YesThreadLocal 變量賦值給 YesRunnable 的一個(gè)成員變量 threadlocalCopy 保存。

3.并修飾 YesRunnable#run 方法,在真正邏輯執(zhí)行前將 threadlocalCopy 賦值給當(dāng)前執(zhí)行線程的上下文,且保存當(dāng)前線程之前的上下文,在執(zhí)行完畢之后,再?gòu)?fù)原此線程的上下文。

4.由于需要在構(gòu)造的時(shí)候復(fù)制所有父線程用到的 YesThreadLocal ,因此需要有個(gè) holder 變量來保存所有用到的 YesThreadLocal ,這樣在構(gòu)造的時(shí)候才好遍歷賦值。

5.并且 holder 變量也需要線程隔離,所以用 ThreadLocal 修飾,并且為了防止 holder 強(qiáng)引用導(dǎo)致內(nèi)存泄漏,所以用 WeakHashMap 存儲(chǔ)。

6.往 holder 添加 YesThreadLocal 的時(shí)機(jī)就在 YesThreadLocal#set 之時(shí)

TransmittableThreadLocal 的實(shí)現(xiàn)

這篇只講 TTL 核心思想(關(guān)鍵路徑),由于篇幅原因其它的不作展開,之后再寫一篇詳細(xì)的。

我上面的實(shí)現(xiàn)其實(shí)就是 TTL 的復(fù)制版,如果你理解了上面的實(shí)現(xiàn),那么接下來對(duì) TTL 介紹理解起來應(yīng)該很簡(jiǎn)單,相當(dāng)于復(fù)習(xí)了。

我們先簡(jiǎn)單看一下 TTL 的使用方式。

1462b3a8-5cd6-11ee-939d-92fbcf53809c.png

使用起來很簡(jiǎn)單對(duì)吧?

TTL 對(duì)標(biāo)上面的 YesThreadLocal ,差別在于它繼承的是 InheritableThreadLocal,因?yàn)檫@樣直接 new TTL 也會(huì)擁有父子線程本地變量的傳遞能力。

1483e7c6-5cd6-11ee-939d-92fbcf53809c.png

我們?cè)賮砜纯?TTL 的 get 和 set 這兩個(gè)核心操作:

14934dce-5cd6-11ee-939d-92fbcf53809c.png

可以看到 get 和 set 其實(shí)就是復(fù)用父類 ThreadLocal 的方法,關(guān)鍵就在于 addThisToHolder,就是我上面分析的將當(dāng)前使用的 TTL 對(duì)象加到 holder 里面。

14aac10c-5cd6-11ee-939d-92fbcf53809c.png

所以,在父線程賦值即執(zhí)行 set 操作之后,父線程里的 holder 就存儲(chǔ)了當(dāng)前的 TTL 對(duì)象了,即上面演示代碼的 ttl.set() 操作。

然后重點(diǎn)就移到了TtlRunnable.get 上了,根據(jù)上面的理解我們知道這里是要進(jìn)行一個(gè)裝飾的操作,這個(gè) get 代碼也比較簡(jiǎn)單,核心就是 new 一個(gè) TtlRunnable 包裝了原始的 task。

14ba6120-5cd6-11ee-939d-92fbcf53809c.png

那我們來看一下它的構(gòu)造方法:

14cc5c68-5cd6-11ee-939d-92fbcf53809c.png

這個(gè) capturedRef 其實(shí)就是父線程本地變量的拷貝,然后 capture() 其實(shí)就等同于copyFatherThreadlocal()

再來看一下 TtlRunnable 裝飾的 run 方法:

14e6099c-5cd6-11ee-939d-92fbcf53809c.png

邏輯很清晰的四步驟:

  1. 拿到父類本地變量拷貝
  2. 賦值給當(dāng)前線程(線程池內(nèi)的某線程),并保存之前的本地變量
  3. 執(zhí)行邏輯
  4. 復(fù)原當(dāng)前線程之前的本地變量

我們?cè)賮矸治鲆幌?capture() 方法,即如何拷貝的。

在 TTL 中是專門定義了一個(gè)靜態(tài)工具類 Transmitter 來實(shí)現(xiàn)上面的 capture、 replay、restore 操作。

1502c258-5cd6-11ee-939d-92fbcf53809c.png

可以看到 capture 的邏輯其實(shí)就是返回一個(gè)快照,而這個(gè)快照就是遍歷 holder 獲取所有存儲(chǔ)在 holder 里面的 TTL ,返回一個(gè)新的 map,還是很簡(jiǎn)單的吧!

這里還有個(gè) captureThreadLocalValues ,這個(gè)是為兼容那些無法將 ThreadLocal 類變更至 TTL ,但是又想復(fù)制傳遞 ThreadLocal 的值而使用的,可以先忽略。

我們?cè)賮砜纯?replay,即如何將父類的本地變量賦值給當(dāng)前線程的。

1519692c-5cd6-11ee-939d-92fbcf53809c.png

邏輯還是很清晰的,先備份,再拷貝覆蓋,最后會(huì)返回備份,拷貝覆蓋的代碼 setTtlValuesTo 很簡(jiǎn)單:

152bc84c-5cd6-11ee-939d-92fbcf53809c.png

就是 for 循環(huán)進(jìn)行了一波 set ,從這里也可以得知為什么上面需要移除父線程沒有的 TTL,因?yàn)檫@里只是進(jìn)行了 set。如果不 remove 當(dāng)前線程的本地變量,那就不是完全繼承自父線程的本地變量了,可能摻雜著之前的本地變量,也就是不干凈了,防止這種干擾,所以還是 remove 了為妙。

最后我們看下 restore 操作:

153fc5a4-5cd6-11ee-939d-92fbcf53809c.png

至此想必對(duì) TTL 的原理應(yīng)該都很清晰了吧!

一些用法

上面我們展示的只是其中一個(gè)用法也就是利用 TtlRunnable.get 來包裝 Runnable。

TTL 還提供了線程池的修飾方法,即 TtlExecutors,比如可以這樣使用:

ExecutorServiceexecutorService=TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(1));

其實(shí)原理也很簡(jiǎn)單,裝飾了一下線程池提交任務(wù)的方法,里面實(shí)現(xiàn)了 TtlRunnable.get 的包裝

155e56c2-5cd6-11ee-939d-92fbcf53809c.png

還有一種使用方式更加透明,即利用 Java Agent 來修飾 JDK 的線程池實(shí)現(xiàn)類,這種方式在使用上基本就是無感知了。

在 Java 的啟動(dòng)參數(shù)加上:-javaagent:path/to/transmittable-thread-local-2.x.y.jar 即可,然后就正常的使用就行,原生的線程池實(shí)現(xiàn)類已經(jīng)悄悄的被改了!

TransmittableThreadLocalttl=newTransmittableThreadLocal<>();
ExecutorServiceexecutorService=Executors.newFixedThreadPool(1);
Runnabletask=newRunnableTask();
executorService.submit(task);

最后

好了,有關(guān) TTL 的原理和用法解釋的都差不多了。

總結(jié)下來的核心操作就是 CRR(Capture/Replay/Restore),拷貝快照、重放快照、復(fù)原上下文。

可能有些人會(huì)疑惑為什么需要復(fù)原,線程池的線程每次執(zhí)行的時(shí)候,如果用了 TTL 那執(zhí)行的線程都會(huì)被覆蓋上下文,沒必要復(fù)原對(duì)吧?

其實(shí)也有人向作者提了這個(gè)疑問,回答是:

  • 線程池滿了且線程池拒絕策略使用的是『CallerRunsPolicy』,這樣執(zhí)行的線程就變成當(dāng)前線程了,那肯定是要復(fù)原的,不然上下文就沒了。
  • 使用ForkJoinPool(包含并行執(zhí)行Stream與CompletableFuture,底層使用ForkJoinPool)的場(chǎng)景,展開的ForkJoinTask會(huì)在調(diào)用線程中直接執(zhí)行。

其實(shí)關(guān)于 TTL 還有很多細(xì)節(jié)可以說,不過篇幅有限,細(xì)節(jié)要說的話得再開一章。不過今天這篇也算把 TTL 的核心思想講完了。

假設(shè)現(xiàn)在有個(gè)面試官問你,我要向線程池里面?zhèn)鬟f ThreadLocal 怎么實(shí)現(xiàn)呀?想必你肯定可以回答出來了~


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

    關(guān)注

    8

    文章

    7134

    瀏覽量

    89479
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4823

    瀏覽量

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

    關(guān)注

    0

    文章

    505

    瀏覽量

    19739

原文標(biāo)題:ThreadLocal的短板,我TTL來補(bǔ)!

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

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    ThreadLocal實(shí)例應(yīng)用

    ThreadLocal相信大家都用過,但你知道他的原理嗎,今天了不起帶大家學(xué)習(xí)ThreadLocalThreadLocal是什么 在多線程編程中,經(jīng)常會(huì)遇到需要在不同線程中共享數(shù)據(jù)的情況
    的頭像 發(fā)表于 09-30 10:19 ?693次閱讀
    <b class='flag-5'>ThreadLocal</b>實(shí)例應(yīng)用

    ThreadLocal的定義、用法及優(yōu)點(diǎn)

    ThreadLocal 簡(jiǎn)介 ThreadLocal是Java中一個(gè)非常重要的線程技術(shù)。它可以讓每個(gè)線程都擁有自己的變量副本,避免了線程間的競(jìng)爭(zhēng)和數(shù)據(jù)泄露問題。在本文中,我們將詳細(xì)介紹
    的頭像 發(fā)表于 09-30 10:14 ?1137次閱讀
    <b class='flag-5'>ThreadLocal</b>的定義、用法及優(yōu)點(diǎn)

    二維插補(bǔ)

    主要任務(wù):以單片機(jī)為控制器,步進(jìn)電機(jī)為執(zhí)行器,構(gòu)建一個(gè)二維插補(bǔ)系統(tǒng),該系統(tǒng)能夠進(jìn)行4個(gè)象限的直線、圓弧插補(bǔ)。目標(biāo):設(shè)計(jì)控制系統(tǒng)硬件電路,編寫插補(bǔ)軟件各種插補(bǔ)功能通過按鍵
    發(fā)表于 02-08 15:47

    補(bǔ)晶振:專家詳解溫補(bǔ)晶振

      你對(duì)溫補(bǔ)晶振了解嗎?或者說你了解溫補(bǔ)晶振多少呢?下面我們跟著松季晶振全面具體的了解溫補(bǔ)晶振。  1、松季電子介紹說:溫補(bǔ)晶振即溫度補(bǔ)償
    發(fā)表于 08-14 16:03

    LVDS與TTL轉(zhuǎn)換

    電路中實(shí)現(xiàn)的是28路TTL轉(zhuǎn)為L(zhǎng)VDS,再轉(zhuǎn)為28路TTL的管腳分配是根據(jù)cameralink的協(xié)議的,檢查后也沒發(fā)現(xiàn)問題,下面圖里
    發(fā)表于 08-04 22:40

    需要什么適應(yīng)TTL電平到電力線?

    你好,高興地發(fā)現(xiàn),PSoC1(CY8C29)現(xiàn)在能夠“房子”PLC IP解決方案。在我看來,這是一個(gè)非常有趣的問題,即使它是一個(gè)資源匱乏的解決方案。的問題是…需要什么適應(yīng)TTL
    發(fā)表于 05-15 08:36

    補(bǔ)光燈的單片機(jī)開發(fā)設(shè)計(jì)

    景完全可以,只要您覺得昏暗的場(chǎng)景可以用它們補(bǔ)光,關(guān)鍵同樣便宜,可以說它是日常攝影照明的理想合作伙伴!補(bǔ)光燈有多種類型,包括環(huán)形,方形,桿形等等多種樣式!閃光燈:常見的閃光燈類型是機(jī)器頂部的熱靴閃光燈。當(dāng)然
    發(fā)表于 06-29 18:00

    改進(jìn)型TTL門電路—抗飽和TTL電路

    改進(jìn)型TTL門電路——抗飽和TTL電路   抗飽和TTL電路是目前傳輸速度較高的一類TTL電路。這種電路由于采用肖特基勢(shì)壘二極管SBD鉗位方法
    發(fā)表于 04-07 00:16 ?2717次閱讀
    改進(jìn)型<b class='flag-5'>TTL</b>門電路—抗飽和<b class='flag-5'>TTL</b>電路

    補(bǔ)終端短板 TD-SCDMA醞釀商用化質(zhì)變

    補(bǔ)終端短板TD醞釀商用化質(zhì)變    “終端還是現(xiàn)在最令人牽掛的部分。”信息產(chǎn)業(yè)部電信研究院一高層對(duì)《第一財(cái)經(jīng)日?qǐng)?bào)》表示,TD-SCDMA網(wǎng)絡(luò)問題不大,而終端的成熟度、品
    發(fā)表于 06-23 09:21 ?276次閱讀

    什么是短板印刷

    什么是短板印刷 短板印刷圖片 短板印刷是
    發(fā)表于 10-13 09:29 ?3060次閱讀

    ThreadLocal發(fā)生內(nèi)存泄漏的原因

    ,就可能會(huì)導(dǎo)致內(nèi)存泄漏。下面,我們將圍繞三個(gè)方面分析 ThreadLocal 內(nèi)存泄漏的問題 ThreadLocal 實(shí)現(xiàn)原理 ThreadLocal為什么會(huì)內(nèi)存泄漏
    的頭像 發(fā)表于 05-05 16:23 ?3717次閱讀

    如何使用ThreadLocal避免內(nèi)存泄漏

    本次給大家介紹重要的工具ThreadLocal。講解內(nèi)容如下,同時(shí)介紹什么場(chǎng)景下發(fā)生內(nèi)存泄漏,如何復(fù)現(xiàn)內(nèi)存泄漏,如何正確使用它避免內(nèi)存泄漏。 ThreadLocal是什么?有哪些用途
    的頭像 發(fā)表于 08-20 09:29 ?4269次閱讀
    如何使用<b class='flag-5'>ThreadLocal</b><b class='flag-5'>來</b>避免內(nèi)存泄漏

    ThreadLocal源碼解析及實(shí)戰(zhàn)應(yīng)用

    ThreadLocal 是一個(gè)關(guān)于創(chuàng)建線程局部變量的類。
    的頭像 發(fā)表于 01-29 14:53 ?491次閱讀

    ThreadLocal基本內(nèi)容與用法

    下面我們就來看看道哥都用的ThreadLocal。 1 ThreadLocal你來自哪里 Since : 1.2 Author : Josh Bloch and Doug Lea 又是并發(fā)大佬們
    的頭像 發(fā)表于 10-13 11:39 ?494次閱讀

    無功補(bǔ)償?shù)墓?b class='flag-5'>補(bǔ)、分補(bǔ)、混補(bǔ)

    的穩(wěn)定性和可靠性。 在實(shí)際應(yīng)用中,無功補(bǔ)償主要分為共補(bǔ)、分補(bǔ)和混補(bǔ)三種方式。 共補(bǔ)是指在電力系統(tǒng)中通過集中式的無功補(bǔ)償設(shè)備補(bǔ)償整個(gè)系統(tǒng)的無
    的頭像 發(fā)表于 12-19 15:47 ?1025次閱讀
    主站蜘蛛池模板: 久久毛片网站 | 美女搜查官被高难度黑人在线播放 | 无码AV动漫精品一区二区免费 | 久久久久综合 | 香蕉动漫库 | 人妻中文字幕无码系列 | 欧美黑人巨大xxxxx | 国产免费福利在线视频 | 中文字幕不卡在线高清 | 24小时日本高清免费看 | 老外的好大c的我好爽 | 色综合 亚洲 自拍 欧洲 | 色内射无码AV | 国语对白嫖老妇胖老太 | 青青草原国产在线观看 | 日本三级按摩推拿按摩 | 美女裸露100%奶头视频 | 国产爱豆剧果冻传媒在线 | 亚洲大片在线观看 | 先锋影音av无码第1页 | 日本边添边摸边做边爱边 | 国产欧美在线亚洲一区刘亦菲 | 韩国无遮羞禁动漫在线观看 | 精品水蜜桃久久久久久久 | 久久久久久91香蕉国产 | 99国产精品免费视频 | 一个人在线观看免费高清视频在线观看 | 中文字幕视频免费在线观看 | 国精一区二区AV在线观看网站 | 蜜桃传媒在线播放 | 麻豆精品2021最新 | 精品午夜久久福利大片免费 | 最近高清日本免费 | 茎身铃口调教 | 综合精品欧美日韩国产在线 | 我解开了岳的乳第一个女人 | 小泽玛丽av无码观看 | 午夜国产高清精品一区免费 | 成人国产免费 | 欧美中文字幕一区二区三区 | 我解开了岳的乳第一个女人 |