java多线程之ThreadLoal详解
一、ThreadLocal簡(jiǎn)介
多線程訪問(wèn)同一個(gè)共享變量時(shí)特別容易出現(xiàn)并發(fā)問(wèn)題,特別是在多個(gè)線程需要對(duì)一個(gè)共享變量進(jìn)行寫(xiě)入時(shí)。為了保證線程安全,一般使用者在訪問(wèn)共享變量時(shí)需要進(jìn)行適當(dāng)?shù)耐?/p>
同步一般是通過(guò)加鎖來(lái)實(shí)現(xiàn)的,但這對(duì)用戶(hù)有一定要求,加重了使用者的負(fù)擔(dān).使用ThredLocal就可以做到,創(chuàng)建一個(gè)變量后,每個(gè)線程對(duì)其訪問(wèn)的時(shí)候訪問(wèn)的是自己創(chuàng)建的變量.
如果你創(chuàng)建了一個(gè)ThreadLocal變量,那么訪問(wèn)這個(gè)變量的每個(gè)線程都會(huì)擁有一個(gè)這個(gè)變量的副本.操作的時(shí)候也是操作的屬于自己這個(gè)線程的變量,從而避免了線程安全問(wèn)題.
二、ThreadLocal使用示例
運(yùn)行結(jié)果如下
threadOne:threadOne local variable threadOne remove after:threadOne local variable threadTwo:threadTwo local variable threadTwo remove after:threadTwo local variable線程O(píng)ne中的代碼3.1通過(guò)set方法設(shè)置了localVariable的值,這其實(shí)設(shè)置的是線程O(píng)ne本地內(nèi)存中的一個(gè)副本,這個(gè)副本線程Two是訪問(wèn)不了的。然后代碼3.2調(diào)用了print函數(shù),代碼1.1通過(guò)get函數(shù)獲取了當(dāng)前線程(線程O(píng)ne)本地內(nèi)存中l(wèi)ocalVariable的值。
線程Two的執(zhí)行類(lèi)似于線程O(píng)ne。
將localVariable.remove 這一句代碼的注釋刪除
static void print(String str) {//1.1 打印當(dāng)前線程本地內(nèi)存中l(wèi)ocalVariable變量的值System.out.println(str + ":" + localVariable.get());//清除當(dāng)前線程本地內(nèi)存中的localVariable的值//localVariable.remove();}運(yùn)行結(jié)果如下所示:
threadOne:threadOne local variable threadOne remove after:null threadTwo:threadTwo local variable threadTwo remove after:null三、ThreadLocal實(shí)現(xiàn)原理
首先看一下ThreadLocal相關(guān)類(lèi)的類(lèi)圖結(jié)構(gòu)
由該圖可知,Thread類(lèi)中有一個(gè)threadLocals和一個(gè)inheritableThreadLocals,它們都是ThreadLocalMap類(lèi)型的變量.而ThreadLocalMap是一個(gè)定制化的Hashmap。在默認(rèn)情況下,每個(gè)線程中的這兩個(gè)變量都為null,只有當(dāng)前線程第一次調(diào)用ThreadLocal的set或者get方法時(shí)才會(huì)創(chuàng)建它們。其實(shí)每個(gè)線程的本地變量不是存放在ThreadLocal實(shí)例里面,而是存放在調(diào)用線程的threadLocals變量里面。
也就是說(shuō),ThreadLocal類(lèi)型的本地變量存放在具體的線程內(nèi)存空間中。ThreadLocal就是一個(gè)工具殼,它通過(guò)set方法把value值放入調(diào)用線程的threadLocals里面并存放起來(lái),當(dāng)調(diào)用線程調(diào)用它的get方法時(shí),再?gòu)漠?dāng)前線程的threadLocals變量里面將其拿出來(lái)使用。
如果調(diào)用線程一直不終止,那么這個(gè)本地變量會(huì)一直存放在調(diào)用線程的threadLocals變量里面,所以當(dāng)不需要使用本地變量時(shí)可以通過(guò)調(diào)用ThreadLocal變量的remove方法,從當(dāng)前線程的threadLocals里面刪除該本地變量。另外,Thread里面的threadLocals為何被設(shè)計(jì)為map結(jié)構(gòu)?很明顯是因?yàn)槊總€(gè)線程可以關(guān)聯(lián)多個(gè)ThreadLocal變量。
總結(jié)
以上是生活随笔為你收集整理的java多线程之ThreadLoal详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python精要(73)-函数传递任意参
- 下一篇: 端计算(1)-wasm