在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

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

什么是ThreadLocal?一文讓你徹底掌握ThreadLocal

OSC開(kāi)源社區(qū) ? 來(lái)源:冰河技術(shù) ? 2023-08-07 11:39 ? 次閱讀

前言

我們都知道,在多線程環(huán)境下訪問(wèn)同一個(gè)共享變量,可能會(huì)出現(xiàn)線程安全的問(wèn)題,為了保證線程安全,我們往往會(huì)在訪問(wèn)這個(gè)共享變量的時(shí)候加鎖,以達(dá)到同步的效果,如下圖所示。

b2620dde-32af-11ee-9e74-dac502259ad0.jpg

對(duì)共享變量加鎖雖然能夠保證線程的安全,但是卻增加了開(kāi)發(fā)人員對(duì)鎖的使用技能,如果鎖使用不當(dāng),則會(huì)導(dǎo)致死鎖的問(wèn)題。而ThreadLocal能夠做到在創(chuàng)建變量后,每個(gè)線程對(duì)變量訪問(wèn)時(shí)訪問(wèn)的是線程自己的本地變量

什么是ThreadLocal?

ThreadLocal是JDK提供的,支持線程本地變量。也就是說(shuō),如果我們創(chuàng)建了一個(gè)ThreadLocal變量,則訪問(wèn)這個(gè)變量的每個(gè)線程都會(huì)有這個(gè)變量的一個(gè)本地副本。如果多個(gè)線程同時(shí)對(duì)這個(gè)變量進(jìn)行讀寫(xiě)操作時(shí),實(shí)際上操作的是線程自己本地內(nèi)存中的變量,從而避免了線程安全的問(wèn)題。

b275f966-32af-11ee-9e74-dac502259ad0.jpg

ThreadLocal使用示例

例如,我們使用ThreadLocal保存并打印相關(guān)的變量信息,程序如下所示。

publicclassThreadLocalTest{

privatestaticThreadLocalthreadLocal=newThreadLocal();

publicstaticvoidmain(String[]args){
//創(chuàng)建第一個(gè)線程
ThreadthreadA=newThread(()->{
threadLocal.set("ThreadA:"+Thread.currentThread().getName());
System.out.println("線程A本地變量中的值為:"+threadLocal.get());
});
//創(chuàng)建第二個(gè)線程
ThreadthreadB=newThread(()->{
threadLocal.set("ThreadB:"+Thread.currentThread().getName());
System.out.println("線程B本地變量中的值為:"+threadLocal.get());
});
//啟動(dòng)線程A和線程B
threadA.start();
threadB.start();
}
}

運(yùn)行程序,打印的結(jié)果信息如下所示。

線程A本地變量中的值為:ThreadA:Thread-0
線程B本地變量中的值為:ThreadB:Thread-1

此時(shí),我們?yōu)榫€程A增加刪除ThreadLocal中的變量的操作,如下所示。

publicclassThreadLocalTest{

privatestaticThreadLocalthreadLocal=newThreadLocal();

publicstaticvoidmain(String[]args){
//創(chuàng)建第一個(gè)線程
ThreadthreadA=newThread(()->{
threadLocal.set("ThreadA:"+Thread.currentThread().getName());
System.out.println("線程A本地變量中的值為:"+threadLocal.get());
threadLocal.remove();
System.out.println("線程A刪除本地變量后ThreadLocal中的值為:"+threadLocal.get());
});
//創(chuàng)建第二個(gè)線程
ThreadthreadB=newThread(()->{
threadLocal.set("ThreadB:"+Thread.currentThread().getName());
System.out.println("線程B本地變量中的值為:"+threadLocal.get());
System.out.println("線程B沒(méi)有刪除本地變量:"+threadLocal.get());
});
//啟動(dòng)線程A和線程B
threadA.start();
threadB.start();
}
}

此時(shí)的運(yùn)行結(jié)果如下所示。

線程A本地變量中的值為:ThreadA:Thread-0
線程B本地變量中的值為:ThreadB:Thread-1
線程B沒(méi)有刪除本地變量:ThreadB:Thread-1
線程A刪除本地變量后ThreadLocal中的值為:null

通過(guò)上述程序我們可以看出,線程A和線程B存儲(chǔ)在ThreadLocal中的變量互不干擾,線程A存儲(chǔ)的變量只能由線程A訪問(wèn),線程B存儲(chǔ)的變量只能由線程B訪問(wèn)。

ThreadLocal原理

首先,我們看下Thread類(lèi)的源碼,如下所示。

publicclassThreadimplementsRunnable{
/***********省略N行代碼*************/
ThreadLocal.ThreadLocalMapthreadLocals=null;
ThreadLocal.ThreadLocalMapinheritableThreadLocals=null;
/***********省略N行代碼*************/
}

由Thread類(lèi)的源碼可以看出,在ThreadLocal類(lèi)中存在成員變量threadLocals和inheritableThreadLocals,這兩個(gè)成員變量都是ThreadLocalMap類(lèi)型的變量,而且二者的初始值都為null。只有當(dāng)前線程第一次調(diào)用ThreadLocal的set()方法或者get()方法時(shí)才會(huì)實(shí)例化變量。

這里需要注意的是:每個(gè)線程的本地變量不是存放在ThreadLocal實(shí)例里面的,而是存放在調(diào)用線程的threadLocals變量里面的。也就是說(shuō),調(diào)用ThreadLocal的set()方法存儲(chǔ)的本地變量是存放在具體線程的內(nèi)存空間中的,而ThreadLocal類(lèi)只是提供了set()和get()方法來(lái)存儲(chǔ)和讀取本地變量的值,當(dāng)調(diào)用ThreadLocal類(lèi)的set()方法時(shí),把要存儲(chǔ)的值放入調(diào)用線程的threadLocals中存儲(chǔ)起來(lái),當(dāng)調(diào)用ThreadLocal類(lèi)的get()方法時(shí),從當(dāng)前線程的threadLocals變量中將存儲(chǔ)的值取出來(lái)。

接下來(lái),我們分析下ThreadLocal類(lèi)的set()、get()和remove()方法的實(shí)現(xiàn)邏輯。

set()方法

set()方法的源代碼如下所示。

publicvoidset(Tvalue){
//獲取當(dāng)前線程
Threadt=Thread.currentThread();
//以當(dāng)前線程為Key,獲取ThreadLocalMap對(duì)象
ThreadLocalMapmap=getMap(t);
//獲取的ThreadLocalMap對(duì)象不為空
if(map!=null)
//設(shè)置value的值
map.set(this,value);
else
//獲取的ThreadLocalMap對(duì)象為空,創(chuàng)建Thread類(lèi)中的threadLocals變量
createMap(t,value);
}

在set()方法中,首先獲取調(diào)用set()方法的線程,接下來(lái),使用當(dāng)前線程作為Key調(diào)用getMap(t)方法來(lái)獲取ThreadLocalMap對(duì)象,getMap(Thread t)的方法源碼如下所示。

ThreadLocalMapgetMap(Threadt){
returnt.threadLocals;
}

可以看到,getMap(Thread t)方法獲取的是線程變量自身的threadLocals成員變量。

在set()方法中,如果調(diào)用getMap(t)方法返回的對(duì)象不為空,則把value值設(shè)置到Thread類(lèi)的threadLocals成員變量中,而傳遞的key為當(dāng)前ThreadLocal的this對(duì)象,value就是通過(guò)set()方法傳遞的值。

如果調(diào)用getMap(t)方法返回的對(duì)象為空,則程序調(diào)用createMap(t, value)方法來(lái)實(shí)例化Thread類(lèi)的threadLocals成員變量。

voidcreateMap(Threadt,TfirstValue){
t.threadLocals=newThreadLocalMap(this,firstValue);
}

也就是創(chuàng)建當(dāng)前線程的threadLocals變量。

get()方法

get()方法的源代碼如下所示。

publicTget(){
//獲取當(dāng)前線程
Threadt=Thread.currentThread();
//獲取當(dāng)前線程的threadLocals成員變量
ThreadLocalMapmap=getMap(t);
//獲取的threadLocals變量不為空
if(map!=null){
//返回本地變量對(duì)應(yīng)的值
ThreadLocalMap.Entrye=map.getEntry(this);
if(e!=null){
@SuppressWarnings("unchecked")
Tresult=(T)e.value;
returnresult;
}
}
//初始化threadLocals成員變量的值
returnsetInitialValue();
}

通過(guò)當(dāng)前線程來(lái)獲取threadLocals成員變量,如果threadLocals成員變量不為空,則直接返回當(dāng)前線程綁定的本地變量,否則調(diào)用setInitialValue()方法初始化threadLocals成員變量的值。

privateTsetInitialValue(){
//調(diào)用初始化Value的方法
Tvalue=initialValue();
Threadt=Thread.currentThread();
//根據(jù)當(dāng)前線程獲取threadLocals成員變量
ThreadLocalMapmap=getMap(t);
if(map!=null)
//threadLocals不為空,則設(shè)置value值
map.set(this,value);
else
//threadLocals為空,創(chuàng)建threadLocals變量
createMap(t,value);
returnvalue;
}

其中,initialValue()方法的源碼如下所示。

protectedTinitialValue(){
returnnull;
}

通過(guò)initialValue()方法的源碼可以看出,這個(gè)方法可以由子類(lèi)覆寫(xiě),在ThreadLocal類(lèi)中,這個(gè)方法直接返回null。

remove()方法

remove()方法的源代碼如下所示。

publicvoidremove(){
//根據(jù)當(dāng)前線程獲取threadLocals成員變量
ThreadLocalMapm=getMap(Thread.currentThread());
if(m!=null)
//threadLocals成員變量不為空,則移除value值
m.remove(this);
}

remove()方法的實(shí)現(xiàn)比較簡(jiǎn)單,首先根據(jù)當(dāng)前線程獲取threadLocals成員變量,不為空,則直接移除value的值。

注意:如果調(diào)用線程一致不終止,則本地變量會(huì)一直存放在調(diào)用線程的threadLocals成員變量中,所以,如果不需要使用本地變量時(shí),可以通過(guò)調(diào)用ThreadLocal的remove()方法,將本地變量從當(dāng)前線程的threadLocals成員變量中刪除,以免出現(xiàn)內(nèi)存溢出的問(wèn)題。

ThreadLocal變量不具有傳遞性

使用ThreadLocal存儲(chǔ)本地變量不具有傳遞性,也就是說(shuō),同一個(gè)ThreadLocal在父線程中設(shè)置值后,在子線程中是無(wú)法獲取到這個(gè)值的,這個(gè)現(xiàn)象說(shuō)明ThreadLocal中存儲(chǔ)的本地變量不具有傳遞性。

接下來(lái),我們來(lái)看一段代碼,如下所示。

publicclassThreadLocalTest{

privatestaticThreadLocalthreadLocal=newThreadLocal();

publicstaticvoidmain(String[]args){
//在主線程中設(shè)置值
threadLocal.set("ThreadLocalTest");
//在子線程中獲取值
Threadthread=newThread(newRunnable(){
@Override
publicvoidrun(){
System.out.println("子線程獲取值:"+threadLocal.get());
}
});
//啟動(dòng)子線程
thread.start();
//在主線程中獲取值
System.out.println("主線程獲取值:"+threadLocal.get());
}
}

運(yùn)行這段代碼輸出的結(jié)果信息如下所示。

主線程獲取值:ThreadLocalTest
子線程獲取值:null

通過(guò)上述程序,我們可以看出在主線程中向ThreadLocal設(shè)置值后,在子線程中是無(wú)法獲取到這個(gè)值的。那有沒(méi)有辦法在子線程中獲取到主線程設(shè)置的值呢?此時(shí),我們可以使用InheritableThreadLocal來(lái)解決這個(gè)問(wèn)題。

InheritableThreadLocal使用示例

InheritableThreadLocal類(lèi)繼承自ThreadLocal類(lèi),它能夠讓子線程訪問(wèn)到在父線程中設(shè)置的本地變量的值,例如,我們將ThreadLocalTest類(lèi)中的threadLocal靜態(tài)變量改寫(xiě)成InheritableThreadLocal類(lèi)的實(shí)例,如下所示。

publicclassThreadLocalTest{

privatestaticThreadLocalthreadLocal=newInheritableThreadLocal();

publicstaticvoidmain(String[]args){
//在主線程中設(shè)置值
threadLocal.set("ThreadLocalTest");
//在子線程中獲取值
Threadthread=newThread(newRunnable(){
@Override
publicvoidrun(){
System.out.println("子線程獲取值:"+threadLocal.get());
}
});
//啟動(dòng)子線程
thread.start();
//在主線程中獲取值
System.out.println("主線程獲取值:"+threadLocal.get());
}
}

此時(shí),運(yùn)行程序輸出的結(jié)果信息如下所示。

主線程獲取值:ThreadLocalTest
子線程獲取值:ThreadLocalTest

可以看到,使用InheritableThreadLocal類(lèi)存儲(chǔ)本地變量時(shí),子線程能夠獲取到父線程中設(shè)置的本地變量。

b2ce9eae-32af-11ee-9e74-dac502259ad0.jpg

InheritableThreadLocal原理

首先,我們來(lái)看下InheritableThreadLocal類(lèi)的源碼,如下所示。

publicclassInheritableThreadLocalextendsThreadLocal{
protectedTchildValue(TparentValue){
returnparentValue;
}

ThreadLocalMapgetMap(Threadt){
returnt.inheritableThreadLocals;
}

voidcreateMap(Threadt,TfirstValue){
t.inheritableThreadLocals=newThreadLocalMap(this,firstValue);
}
}

由InheritableThreadLocal類(lèi)的源代碼可知,InheritableThreadLocal類(lèi)繼承自ThreadLocal類(lèi),并且重寫(xiě)了ThreadLocal類(lèi)的childValue()方法、getMap()方法和createMap()方法。也就是說(shuō),當(dāng)調(diào)用ThreadLocal的set()方法時(shí),創(chuàng)建的是當(dāng)前Thread線程的inheritableThreadLocals成員變量而不再是threadLocals成員變量。

這里,我們需要思考一個(gè)問(wèn)題:InheritableThreadLocal類(lèi)的childValue()方法是何時(shí)被調(diào)用的呢?這就需要我們來(lái)看下Thread類(lèi)的構(gòu)造方法了,如下所示。

publicThread(){
init(null,null,"Thread-"+nextThreadNum(),0);
}

publicThread(Runnabletarget){
init(null,target,"Thread-"+nextThreadNum(),0);
}

Thread(Runnabletarget,AccessControlContextacc){
init(null,target,"Thread-"+nextThreadNum(),0,acc,false);
}

publicThread(ThreadGroupgroup,Runnabletarget){
init(group,target,"Thread-"+nextThreadNum(),0);
}

publicThread(Stringname){
init(null,null,name,0);
}

publicThread(ThreadGroupgroup,Stringname){
init(group,null,name,0);
}

publicThread(Runnabletarget,Stringname){
init(null,target,name,0);
}

publicThread(ThreadGroupgroup,Runnabletarget,Stringname){
init(group,target,name,0);
}

publicThread(ThreadGroupgroup,Runnabletarget,Stringname,
longstackSize){
init(group,target,name,stackSize);
}

可以看到,Thread類(lèi)的構(gòu)造方法最終調(diào)用的是init()方法,那我們就來(lái)看下init()方法,如下所示。

privatevoidinit(ThreadGroupg,Runnabletarget,Stringname,
longstackSize,AccessControlContextacc,
booleaninheritThreadLocals){
/************省略部分源碼************/
if(inheritThreadLocals&&parent.inheritableThreadLocals!=null)
this.inheritableThreadLocals=
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/*StashthespecifiedstacksizeincasetheVMcares*/
this.stackSize=stackSize;

/*SetthreadID*/
tid=nextThreadID();
}

可以看到,在init()方法中會(huì)判斷傳遞的inheritThreadLocals變量是否為true,同時(shí)父線程中的inheritableThreadLocals是否為null,如果傳遞的inheritThreadLocals變量為true,同時(shí),父線程中的inheritableThreadLocals不為null,則調(diào)用ThreadLocal類(lèi)的createInheritedMap()方法。

staticThreadLocalMapcreateInheritedMap(ThreadLocalMapparentMap){
returnnewThreadLocalMap(parentMap);
}

在createInheritedMap()中,使用父線程的inheritableThreadLocals變量作為參數(shù)創(chuàng)建新的ThreadLocalMap對(duì)象。然后在Thread類(lèi)的init()方法中會(huì)將這個(gè)ThreadLocalMap對(duì)象賦值給子線程的inheritableThreadLocals成員變量。

接下來(lái),我們來(lái)看看ThreadLocalMap的構(gòu)造函數(shù)都干了啥,如下所示。

privateThreadLocalMap(ThreadLocalMapparentMap){
Entry[]parentTable=parentMap.table;
intlen=parentTable.length;
setThreshold(len);
table=newEntry[len];

for(intj=0;jkey=(ThreadLocal)e.get();
if(key!=null){
//調(diào)用重寫(xiě)的childValue方法
Objectvalue=key.childValue(e.value);
Entryc=newEntry(key,value);
inth=key.threadLocalHashCode&(len-1);
while(table[h]!=null)
h=nextIndex(h,len);
table[h]=c;
size++;
}
}
}
}

在ThreadLocalMap的構(gòu)造函數(shù)中,調(diào)用了InheritableThreadLocal類(lèi)重寫(xiě)的childValue()方法。而InheritableThreadLocal類(lèi)通過(guò)重寫(xiě)getMap()方法和createMap()方法,讓本地變量保存到了Thread線程的inheritableThreadLocals變量中,線程通過(guò)InheritableThreadLocal類(lèi)的set()方法和get()方法設(shè)置變量時(shí),就會(huì)創(chuàng)建當(dāng)前線程的inheritableThreadLocals變量。

此時(shí),如果父線程創(chuàng)建子線程,在Thread類(lèi)的構(gòu)造函數(shù)中會(huì)把父線程中的inheritableThreadLocals變量里面的本地變量復(fù)制一份保存到子線程的inheritableThreadLocals變量中。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(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)投訴
  • 存儲(chǔ)器
    +關(guān)注

    關(guān)注

    38

    文章

    7640

    瀏覽量

    166631
  • Thread編程
    +關(guān)注

    關(guān)注

    0

    文章

    3

    瀏覽量

    942
  • 內(nèi)存溢出
    +關(guān)注

    關(guān)注

    0

    文章

    10

    瀏覽量

    1323

原文標(biāo)題:一文讓你徹底掌握ThreadLocal

文章出處:【微信號(hào):OSC開(kāi)源社區(qū),微信公眾號(hào):OSC開(kāi)源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

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

    徹底掌握MOS管

    基礎(chǔ)知識(shí)中 MOS 部分遲遲未整理,實(shí)際分享的電路中大部分常用電路都用到了MOS管, 今天勢(shì)必要來(lái)篇文章,徹底掌握mos管!
    發(fā)表于 07-05 11:56 ?3.2w次閱讀

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

    ThreadLocal相信大家都用過(guò),但知道他的原理嗎,今天了不起帶大家學(xué)習(xí)ThreadLocalThreadLocal是什么 在多線程編程中,經(jīng)常會(huì)遇到需要在不同線程中共享數(shù)據(jù)
    的頭像 發(fā)表于 09-30 10:19 ?863次閱讀
    <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ù)泄露問(wèn)題。在本文中,我們將詳細(xì)介紹
    的頭像 發(fā)表于 09-30 10:14 ?1386次閱讀
    <b class='flag-5'>ThreadLocal</b>的定義、用法及優(yōu)點(diǎn)

    徹底理解DFT

    從本期開(kāi)始,E課網(wǎng)將為大家推出系列的‘徹底理解’專(zhuān)題。該專(zhuān)題的目的是大家更好的理解并弄清楚設(shè)計(jì)過(guò)程中所面臨的各種問(wèn)題,在對(duì)問(wèn)題充分理
    發(fā)表于 05-25 15:32

    份白皮書(shū),徹底了解比特幣

    份白皮書(shū),徹底了解比特幣
    發(fā)表于 03-05 15:02 ?26次下載
    <b class='flag-5'>一</b>份白皮書(shū),<b class='flag-5'>讓</b><b class='flag-5'>你</b><b class='flag-5'>徹底</b>了解比特幣

    8張圖徹底理解晶體管開(kāi)關(guān)電路圖

    8張徹底理解晶體管開(kāi)關(guān)電路圖
    的頭像 發(fā)表于 02-05 12:41 ?1.2w次閱讀

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

    前言 ThreadLocal 的作用是提供線程內(nèi)的局部變量,這種變量在線程的生命周期內(nèi)起作用,減少同個(gè)線程內(nèi)多個(gè)函數(shù)或者組件之間些公共變量的傳遞的復(fù)雜度。但是如果濫用 ThreadLoca
    的頭像 發(fā)表于 05-05 16:23 ?3888次閱讀

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

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

    FastThreadLocal快在哪里

    netty還要自己造個(gè)FastThreadLocal?FastThreadLocal快在哪里? 這需要從jdk ThreadLocal的本身說(shuō)起。如下圖: 在java線程中,每個(gè)線程都有個(gè)
    的頭像 發(fā)表于 09-13 09:17 ?1464次閱讀

    ThreadLocal的作用以及應(yīng)用場(chǎng)景

    個(gè)簡(jiǎn)單的例子:目前有100個(gè)學(xué)生等待簽字,但是老師只有個(gè)筆,那老師只能按順序的分給每個(gè)學(xué)生,等待A學(xué)生簽字完成然后將筆交給B學(xué)生,這就類(lèi)似Lock,Synchronized的方式。而ThreadLocal是,老師直接拿出一
    的頭像 發(fā)表于 09-19 10:56 ?1617次閱讀

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

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

    ThreadLocal是什么

    和HashMap的最大的不同在于,ThreadLocalMap結(jié)構(gòu)非常簡(jiǎn)單,沒(méi)有next引用,也就是說(shuō)ThreadLocalMap中解決Hash沖突的方式并非鏈表的方式,而是采用線性探測(cè)的方式。
    的頭像 發(fā)表于 01-30 11:36 ?1716次閱讀

    ThreadLocal父子線程之間該如何傳遞數(shù)據(jù)?

    比如會(huì)有以下的這種代碼的實(shí)現(xiàn)。在子線程中調(diào)用 get 時(shí),我們拿到的 Thread 對(duì)象是當(dāng)前子線程對(duì)象,對(duì)吧,每個(gè)線程都有自己獨(dú)立的 ThreadLocal,那么當(dāng)前子線程
    的頭像 發(fā)表于 02-20 11:26 ?1151次閱讀

    掌握Linux常用命令

    掌握Linux40個(gè)命令
    的頭像 發(fā)表于 04-03 11:38 ?800次閱讀

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

    下面我們就來(lái)看看道哥都用的ThreadLocal。 1 ThreadLocal來(lái)自哪里 Since : 1.2 Author : Josh Bloch and Doug Lea 又是并發(fā)大佬們
    的頭像 發(fā)表于 10-13 11:39 ?669次閱讀
    主站蜘蛛池模板: 超黄视频在线观看 | 色综合99 | www成人在线观看 | 日本最新免费网站 | 视频一区二区在线观看 | 国产精品美女免费视频观看 | 色综合久久久久综合99 | 新版天堂资源中文在线 | 在线视频一区二区 | 久久69 | 国产毛片毛片精品天天看 | 婷婷激情电影 | 夜色福利久久久久久777777 | 久久国产精品免费专区 | 美女视频黄a视频免费全过程 | 91在线免费看 | 国产日日操 | 日本亚洲卡一卡2卡二卡三卡四卡 | 1300部小u女视频免费 | 国产黄色高清视频 | 91色在线观看| 1024在线观看你懂的 | 久久精品隔壁老王影院 | 97国内精品久久久久久久影视 | 欧美亚洲视频一区 | 五月婷婷综合基地 | 中文一区在线 | 亚洲综合涩 | 在线色综合 | 朱元璋传奇1998王耿豪版 | 成人剧场 | 久久亚洲国产午夜精品理论片 | 日本综合在线 | 午夜视频黄 | 老司机成人精品视频lsj | baoyu777永久免费视频 | 性欧美日韩 | 欧美精品videosex极品 | 免费aa| 手机毛片在线 | 五月婷婷色播 |