大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

面試題首頁 > 多線程面試題

ThreadLocal面試題

001什么是ThreadLocal?

從字面上理解ThreadLocal就是“線程局部變量”的意思。簡單的說就是,一個ThreadLocal在一個線程中是共享的,在不同線程之間又是隔離的(每個線程都只能看到自己線程的值)。
學習一個類之前我們需要了解一個類的API,這也是我們學習類的入口。而ThreadLocal類的API相當簡單。
在這里面比較重要的就是,get、set、remove了,這三個方法是對這個變量進行操作的關鍵。set用于賦值操作,get用于獲取變量中的值,remove就是刪除當前這個變量的值。需要注意的是initialValue方法會在第一次調用時被觸發,用于初始化當前變量值,例如在下列代碼中我們需要創建一個ThreadLocal,用于創建一個與線程綁定的Connection對象:

ThreadLocal connection = new ThreadLocal(){
? ? public Connection initialValue(){
? ? ? ? return DriverManager.getConnection(…);
? ? }
});

為什么我們將ThreadLocal說成變量,我們姑且可以這么理解,每個ThreadLocal實例中都可以保存一個值(基本數據類型值或者引用類型的引用值),而內部保存的值是可以修改的,而這樣的特性與變量的特性及其相似,變量不就是用來保存一個值的嗎?也就是說每一個ThreadLocal實例就類似于一個變量名,不同的ThreadLocal實例就是不同的變量名,它們內部會存有一個值(暫時這么理解)在后面的描述中所說的“ThreadLocal變量或者是線程變量”代表的就是ThreadLocal類的實例。我們通過重寫initialValue方法指定ThreadLocal變量的初始值,默認情況下initialValue返回的是null。
 

002ThreadLocal的具體實現?

接下來我們就來動手實踐一下,來理解前面沒有理解的那句話:一個ThreadLocal在一個線程中是共享的,在不同線程之間又是隔離的(每個線程都只能看到自己線程的值)

public class ThreadLocalTest {
?? ?private static ThreadLocal<Integer> num = new ThreadLocal<Integer>() {
?? ??? ?// 重寫這個方法,可以修改“線程變量”的初始值,默認是null
?? ??? ?@Override
?? ??? ?protected Integer initialValue() {
?? ??? ??? ?return 0;
?? ??? ?}
?? ?};
?
?? ?public static void main(String[] args) {
?? ??? ?// 創建一號線程
?? ??? ?new Thread(new Runnable() {
?? ??? ??? ?@Override
?? ??? ??? ?public void run() {
?? ??? ??? ??? ?// 在一號線程中將ThreadLocal變量設置為1
?? ??? ??? ??? ?num.set(1);
?? ??? ??? ??? ?System.out.println("一號線程中ThreadLocal變量中保存的值為:" + num.get());
?? ??? ??? ?}
?? ??? ?}).start();
?
?? ??? ?// 創建二號線程
?? ??? ?new Thread(new Runnable() {
?? ??? ??? ?@Override
?? ??? ??? ?public void run() {
?? ??? ??? ??? ?num.set(2);
?? ??? ??? ??? ?System.out.println("二號線程中ThreadLocal變量中保存的值為:" + num.get());
?? ??? ??? ?}
?? ??? ?}).start();
?
?? ??? ?//為了讓一二號線程執行完畢,讓主線程睡500ms
?? ??? ?try {
?? ??? ??? ?Thread.sleep(500);
?? ??? ?} catch (InterruptedException e) {
?? ??? ??? ?// TODO Auto-generated catch block
?? ??? ??? ?e.printStackTrace();
?? ??? ?}
?? ??? ?
?? ??? ?System.out.println("主線程中ThreadLocal變量中保存的值:" + num.get());
?? ?}
}

上面的代碼中在類中創建了一個靜態的“ThreadLocal變量”,在主線程中創建兩個線程,在這兩個線程中分別設置ThreadLocal變量為1和2。然后等待一號和二號線程執行完畢后,在主線程中查看ThreadLocal變量的值。
程序結果及分析:
程序結果重點看的是主線程輸出的是0,如果是一個普通變量,在一號線程和二號線程中將普通變量設置為1和2,那么在一二號線程執行完畢后在打印這個變量,輸出的值肯定是1或者2(到底輸出哪一個由操作系統的線程調度邏輯有關)。但使用ThreadLocal變量通過兩個線程賦值后,在主線程程中輸出的卻是初始值0。在這也就是為什么“一個ThreadLocal在一個線程中是共享的,在不同線程之間又是隔離的”,每個線程都只能看到自己線程的值,這也就是ThreadLocal的核心作用:實現線程范圍的局部變量。
 

003ThreadLocal的原理分析?

我們還是將最后結論擺在前面,每個Thread對象都有一個ThreadLocalMap,當創建一個ThreadLocal的時候,就會將該ThreadLocal對象添加到該Map中,其中鍵就是ThreadLocal,值可以是任意類型。也就是說,想要存入的ThreadLocal中的數據實際上并沒有存到ThreadLocal對象中去,而是以這個ThreadLocal實例作為key存到了當前線程中的一個Map中去了,獲取ThreadLocal的值時同樣也是這個道理。這也就是為什么ThreadLocal可以實現線程之間隔離的原因了。
總結:
1)ThreadLocal的作用:實現線程范圍內的局部變量,即ThreadLocal在一個線程中是共享的,在不同線程之間是隔離的。
2)ThreadLocal的原理:ThreadLocal存入值時使用當前ThreadLocal實例作為key,存入當前線程對象中的Map中去。最開始在看源碼之前,我以為是以當前線程對象作為key將對象存入到ThreadLocal中的Map中去。

004ThreadLocal和Synchonized區別?

兩者都用于解決多線程并發訪問。但是ThreadLocal與synchronized有本質的區別。Synchronized用于線程間的數據共享,而ThreadLocal則用于線程間的數據隔離。Synchronized是利用鎖的機制,使變量或代碼塊在某一時該只能被一個線程訪問。而ThreadLocal為每一個線程都提供了變量的副本,使得每個線程在某一時間訪問到的并不是同一個對象,這樣就隔離了多個線程對數據的數據共享。而Synchronized卻正好相反,它用于在多個線程間通信時能夠獲得數據共享。

005ThreadLocal內存泄漏以及解決方案?

如果ThreadLocal沒有外部強引用,那么在發生垃圾回收的時候,ThreadLocal就必定會被回收,而ThreadLocal又作為Map中的key,ThreadLocal被回收就會導致一個key為null的entry,外部就無法通過key來訪問這個entry,垃圾回收也無法回收,這就造成了內存泄漏
解決方案:每次使用完ThreadLocal都調用它的remove()方法清除數據,或者按照JDK建議將ThreadLocal變量定義成private static,這樣就一直存在ThreadLocal的強引用,也就能保證任何時候都能通過ThreadLocal的弱引用訪問到Entry的value值,進而清除掉。

目錄

返回頂部
主站蜘蛛池模板: 日韩欧美亚州 | 国产精品日韩一区二区三区 | 毛片基地免费视频a | 中文字幕一区视频一线 | 九九精品久久久久久噜噜 | 91福利国产在线观看一区二区 | www操操| 欧美大片在线观看成人 | 福利视频久久 | 一区二区三区四区亚洲 | 视频在线观看一区 | 亚洲日韩精品欧美一区二区一 | 欧美日韩第二页 | 欧美一区二区在线免费观看 | 久久er热在这里只有精品85 | 91免费国产高清观看 | 国产区精品一区二区不卡中文 | 伊人网伊人网 | 麻豆成人久久精品二区三 | 亚洲成aⅴ人片在线观 | 伊人精品影院一本到欧美 | 一级毛片子| 久久久精品成人免费看 | 99精品国产免费久久国语 | 欧美三级一区二区三区 | 成人a免费视频播放 | 亚洲国产一区二区a毛片日本 | 日韩欧美一级毛片视频免费 | 影音先锋在线亚洲精品推荐 | 女人182毛片a级毛片 | 99精品国产福利在线观看 | 久久一本一区二区三区 | 久久精品国产在热久久2019 | 亚洲a视频在线 | 国产精品免费福利 | 亚洲精品综合久久中文字幕 | 欧美三区在线 | 老司机午夜在线视频免费观 | 五月婷婷激情六月 | 91中文字幕视频 | 模特精品一区二区三区 |