中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

有關ThreadLocal的面試題你真的懂了嗎

發布時間:2020-10-20 07:20:26 來源:腳本之家 閱讀:187 作者:匠心零度 欄目:編程語言

說明

面試官:講講你對ThreadLocal的一些理解。

那么我們該怎么回答呢????你也可以思考下,下面看看零度的思考;

  • ThreadLocal用在什么地方?
  • ThreadLocal一些細節!
  • ThreadLocal的最佳實踐!
  • 思考

ThreadLocal用在什么地方?

討論ThreadLocal用在什么地方前,我們先明確下,如果僅僅就一個線程,那么都不用談ThreadLocal的,ThreadLocal是用在多線程的場景的!!!

ThreadLocal歸納下來就2類用途:

  • 保存線程上下文信息,在任意需要的地方可以獲取!!!
  • 線程安全的,避免某些情況需要考慮線程安全必須同步帶來的性能損失!!!

保存線程上下文信息,在任意需要的地方可以獲取!!!

由于ThreadLocal的特性,同一線程在某地方進行設置,在隨后的任意地方都可以獲取到。從而可以用來保存線程上下文信息。

常用的比如每個請求怎么把一串后續關聯起來,就可以用ThreadLocal進行set,在后續的任意需要記錄日志的方法里面進行get獲取到請求id,從而把整個請求串起來。

還有比如Spring的事務管理,用ThreadLocal存儲Connection,從而各個DAO可以獲取同一Connection,可以進行事務回滾,提交等操作。

備注: ThreadLocal的這種用處,很多時候是用在一些優秀的框架里面的,一般我們很少接觸,反而下面的場景我們接觸的更多一些!

線程安全的,避免某些情況需要考慮線程安全必須同步帶來的性能損失!!!
ThreadLocal為解決多線程程序的并發問題提供了一種新的思路。但是ThreadLocal也有局限性,我們來看看阿里規范:

有關ThreadLocal的面試題你真的懂了嗎

每個線程往ThreadLocal中讀寫數據是線程隔離,互相之間不會影響的,所以ThreadLocal無法解決共享對象的更新問題!

由于不需要共享信息,自然就不存在競爭問題了,從而保證了某些情況下線程的安全,以及避免了某些情況需要考慮線程安全必須同步帶來的性能損失!!!

這類場景阿里規范里面也提到了:

有關ThreadLocal的面試題你真的懂了嗎

ThreadLocal一些細節!

ThreaLocal使用示例代碼:

public class ThreadLocalTest {
private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
public static void main(String[] args) {
new Thread(() -> {
try {
for (int i = 0; i < 100; i++) {
threadLocal.set(i);
System.out.println(Thread.currentThread().getName() + "====" + threadLocal.get());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} finally {
threadLocal.remove();
}
}, "threadLocal1").start();
new Thread(() -> {
try {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "====" + threadLocal.get());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} finally {
threadLocal.remove();
}
}, "threadLocal2").start();
}
}

代碼截圖:

有關ThreadLocal的面試題你真的懂了嗎

代碼運行結果:

有關ThreadLocal的面試題你真的懂了嗎

從運行的結果我們可以看到threadLocal1進行set值對threadLocal2并沒有任何影響!

Thread、ThreadLocalMap、ThreadLocal總覽圖

有關ThreadLocal的面試題你真的懂了嗎

有關ThreadLocal的面試題你真的懂了嗎

Thread類有屬性變量threadLocals (類型是ThreadLocal.ThreadLocalMap),也就是說每個線程有一個自己的ThreadLocalMap ,所以每個線程往這個ThreadLocal中讀寫隔離的,并且是互相不會影響的。

一個ThreadLocal只能存儲一個Object對象,如果需要存儲多個Object對象那么就需要多個ThreadLocal!!!

如圖:

有關ThreadLocal的面試題你真的懂了嗎

看到上面的幾個圖,大概思路應該都清晰了,我們Entry的key指向ThreadLocal用虛線表示弱引用 ,下面我們來看看ThreadLocalMap:

有關ThreadLocal的面試題你真的懂了嗎

java對象的引用包括 : 強引用,軟引用,弱引用,虛引用 。

因為這里涉及到弱引用,簡單說明下:

弱引用也是用來描述非必需對象的,當JVM進行垃圾回收時,無論內存是否充足,該對象僅僅被弱引用關聯,那么就會被回收。

當僅僅只有ThreadLocalMap中的Entry的key指向ThreadLocal的時候,ThreadLocal會進行回收的!!!

ThreadLocal被垃圾回收后,在ThreadLocalMap里對應的Entry的鍵值會變成null,但是Entry是強引用,那么Entry里面存儲的Object,并沒有辦法進行回收,所以ThreadLocalMap 做了一些額外的回收工作。

有關ThreadLocal的面試題你真的懂了嗎

雖然做了但是也會存在內存泄漏風險(我沒有遇到過,網上很多類似場景,所以會提到后面的ThreadLocal最佳實踐!!!)

ThreadLocal的最佳實踐!

ThreadLocal被垃圾回收后,在ThreadLocalMap里對應的Entry的鍵值會變成null,但是Entry是強引用,那么Entry里面存儲的Object,并沒有辦法進行回收,所以ThreadLocalMap 做了一些額外的回收工作。

有關ThreadLocal的面試題你真的懂了嗎

備注: 很多時候,我們都是用在線程池的場景,程序不停止,線程基本不會銷毀!!!

由于線程的生命周期很長,如果我們往ThreadLocal里面set了很大很大的Object對象,雖然set、get等等方法在特定的條件會調用進行額外的清理,但是ThreadLocal被垃圾回收后,在ThreadLocalMap里對應的Entry的鍵值會變成null,但是后續在也沒有操作set、get等方法了。

所以最佳實踐,應該在我們不使用的時候,主動調用remove方法進行清理。

有關ThreadLocal的面試題你真的懂了嗎

這里把ThreadLocal定義為static還有一個好處就是,由于ThreadLocal有強引用在,那么在ThreadLocalMap里對應的Entry的鍵會永遠存在,那么執行remove的時候就可以正確進行定位到并且刪除!!!

最佳實踐做法應該為:

try {
// 其它業務邏輯
} finally {
threadLocal對象.remove();
}

思考

如果面試的時候,可以把上面的內容都可以講到,個人覺得就非常好了,回答的就挺完美了。但是如果你可以進行下面的回答,那么就更完美了。

對于ThreadLocal,我在看Netty源碼的時候,還了解過FastThreadLocal,xxxxx一些列內容,那就是一個升級了。

有關ThreadLocal的面試題你真的懂了嗎

在我本地進行測試,FastThreadLocal的吞吐量是jdkThreadLocal的3倍左右。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

桓仁| 雷山县| 南乐县| 汝州市| 台东市| 河间市| 宕昌县| 鄂托克旗| 杭锦旗| 廊坊市| 阿勒泰市| 揭阳市| 高安市| 扶余县| 连城县| 襄垣县| 龙岩市| 天峻县| 威海市| 轮台县| 泗水县| 安化县| 墨竹工卡县| 日照市| 余庆县| 杭锦后旗| 无棣县| 盈江县| 图木舒克市| 文化| 吉林省| 赞皇县| 稷山县| 栖霞市| 东港市| 手游| 师宗县| 抚州市| 辽源市| 贡觉县| 白玉县|