欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

有關(guān)ThreadLocal的面試題你真的懂了嗎

 更新時(shí)間:2019年06月20日 08:39:24   作者:匠心零度  
這篇文章主要介紹了面試題ThreadLocal,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

說明

面試官:講講你對(duì)ThreadLocal的一些理解。

那么我們?cè)撛趺椿卮鹉?????你也可以思考下,下面看看零度的思考?/p>

  • ThreadLocal用在什么地方?
  • ThreadLocal一些細(xì)節(jié)!
  • ThreadLocal的最佳實(shí)踐!
  • 思考

ThreadLocal用在什么地方?

討論ThreadLocal用在什么地方前,我們先明確下,如果僅僅就一個(gè)線程,那么都不用談ThreadLocal的,ThreadLocal是用在多線程的場(chǎng)景的!?。?/p>

ThreadLocal歸納下來就2類用途:

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

保存線程上下文信息,在任意需要的地方可以獲?。。。?br />

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

常用的比如每個(gè)請(qǐng)求怎么把一串后續(xù)關(guān)聯(lián)起來,就可以用ThreadLocal進(jìn)行set,在后續(xù)的任意需要記錄日志的方法里面進(jìn)行g(shù)et獲取到請(qǐng)求id,從而把整個(gè)請(qǐng)求串起來。

還有比如Spring的事務(wù)管理,用ThreadLocal存儲(chǔ)Connection,從而各個(gè)DAO可以獲取同一Connection,可以進(jìn)行事務(wù)回滾,提交等操作。

備注: ThreadLocal的這種用處,很多時(shí)候是用在一些優(yōu)秀的框架里面的,一般我們很少接觸,反而下面的場(chǎng)景我們接觸的更多一些!

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

每個(gè)線程往ThreadLocal中讀寫數(shù)據(jù)是線程隔離,互相之間不會(huì)影響的,所以ThreadLocal無法解決共享對(duì)象的更新問題!

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

這類場(chǎng)景阿里規(guī)范里面也提到了:

ThreadLocal一些細(xì)節(jié)!

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();
}
}

代碼截圖:

代碼運(yùn)行結(jié)果:

從運(yùn)行的結(jié)果我們可以看到threadLocal1進(jìn)行set值對(duì)threadLocal2并沒有任何影響!

Thread、ThreadLocalMap、ThreadLocal總覽圖

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

一個(gè)ThreadLocal只能存儲(chǔ)一個(gè)Object對(duì)象,如果需要存儲(chǔ)多個(gè)Object對(duì)象那么就需要多個(gè)ThreadLocal?。?!

如圖:

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

java對(duì)象的引用包括 : 強(qiáng)引用,軟引用,弱引用,虛引用 。

因?yàn)檫@里涉及到弱引用,簡(jiǎn)單說明下:

弱引用也是用來描述非必需對(duì)象的,當(dāng)JVM進(jìn)行垃圾回收時(shí),無論內(nèi)存是否充足,該對(duì)象僅僅被弱引用關(guān)聯(lián),那么就會(huì)被回收。

當(dāng)僅僅只有ThreadLocalMap中的Entry的key指向ThreadLocal的時(shí)候,ThreadLocal會(huì)進(jìn)行回收的!??!

ThreadLocal被垃圾回收后,在ThreadLocalMap里對(duì)應(yīng)的Entry的鍵值會(huì)變成null,但是Entry是強(qiáng)引用,那么Entry里面存儲(chǔ)的Object,并沒有辦法進(jìn)行回收,所以ThreadLocalMap 做了一些額外的回收工作。

雖然做了但是也會(huì)存在內(nèi)存泄漏風(fēng)險(xiǎn)(我沒有遇到過,網(wǎng)上很多類似場(chǎng)景,所以會(huì)提到后面的ThreadLocal最佳實(shí)踐?。。。?/p>

ThreadLocal的最佳實(shí)踐!

ThreadLocal被垃圾回收后,在ThreadLocalMap里對(duì)應(yīng)的Entry的鍵值會(huì)變成null,但是Entry是強(qiáng)引用,那么Entry里面存儲(chǔ)的Object,并沒有辦法進(jìn)行回收,所以ThreadLocalMap 做了一些額外的回收工作。

備注: 很多時(shí)候,我們都是用在線程池的場(chǎng)景,程序不停止,線程基本不會(huì)銷毀!??!

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

所以最佳實(shí)踐,應(yīng)該在我們不使用的時(shí)候,主動(dòng)調(diào)用remove方法進(jìn)行清理。

這里把ThreadLocal定義為static還有一個(gè)好處就是,由于ThreadLocal有強(qiáng)引用在,那么在ThreadLocalMap里對(duì)應(yīng)的Entry的鍵會(huì)永遠(yuǎn)存在,那么執(zhí)行remove的時(shí)候就可以正確進(jìn)行定位到并且刪除?。?!

最佳實(shí)踐做法應(yīng)該為:

try {
// 其它業(yè)務(wù)邏輯
} finally {
threadLocal對(duì)象.remove();
}

思考

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

對(duì)于ThreadLocal,我在看Netty源碼的時(shí)候,還了解過FastThreadLocal,xxxxx一些列內(nèi)容,那就是一個(gè)升級(jí)了。

在我本地進(jìn)行測(cè)試,F(xiàn)astThreadLocal的吞吐量是jdkThreadLocal的3倍左右。

相關(guān)文章

  • IDEA:Error running,Command line is too long.解決方案

    IDEA:Error running,Command line is too&n

    這篇文章主要介紹了IDEA:Error running,Command line is too long.解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • maven的pom.xml中repositories和distributionManagement使用

    maven的pom.xml中repositories和distributionManagement使用

    這篇文章主要介紹了maven的pom.xml中repositories和distributionManagement使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 手把手教學(xué)Win10同時(shí)安裝兩個(gè)版本的JDK并隨時(shí)切換(JDK8和JDK11)

    手把手教學(xué)Win10同時(shí)安裝兩個(gè)版本的JDK并隨時(shí)切換(JDK8和JDK11)

    最近在學(xué)習(xí)JDK11的一些新特性,但是日常使用基本上都是基于JDK8,因此,需要在win環(huán)境下安裝多個(gè)版本的JDK,下面這篇文章主要給大家介紹了手把手教學(xué)Win10同時(shí)安裝兩個(gè)版本的JDK(JDK8和JDK11)并隨時(shí)切換的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • SpringBoot優(yōu)化接口響應(yīng)時(shí)間的九個(gè)技巧

    SpringBoot優(yōu)化接口響應(yīng)時(shí)間的九個(gè)技巧

    在實(shí)際開發(fā)中,提升接口響應(yīng)速度是一件挺重要的事,特別是在面臨大量用戶請(qǐng)求的時(shí)候,本文為大家整理了9個(gè)SpringBoot優(yōu)化接口響應(yīng)時(shí)間的技巧,希望對(duì)大家有所幫助
    2024-01-01
  • Mybatis insert方法主鍵回填和自定義操作

    Mybatis insert方法主鍵回填和自定義操作

    這篇文章主要介紹了Mybatis insert方法主鍵回填和自定義操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java源碼解析阻塞隊(duì)列ArrayBlockingQueue介紹

    Java源碼解析阻塞隊(duì)列ArrayBlockingQueue介紹

    今天小編就為大家分享一篇關(guān)于Java源碼解析阻塞隊(duì)列ArrayBlockingQueue介紹,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Java中的gateway自定義過濾器詳解

    Java中的gateway自定義過濾器詳解

    這篇文章主要介紹了Java中的gateway自定義過濾器詳解,過濾器是指gateway在路由過程中(A地址路由到B地址)生效進(jìn)行過濾操作的,所有首先你得先配一個(gè)地址路由,本文提供了部分實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2023-11-11
  • java捕獲AOP級(jí)別的異常并將其傳遞到Controller層

    java捕獲AOP級(jí)別的異常并將其傳遞到Controller層

    如何在一個(gè)現(xiàn)代的Java應(yīng)用中,捕獲AOP(面向切面編程)級(jí)別的異常,并將這些異常傳遞到Controller層進(jìn)行合適的處理,異常處理在構(gòu)建可靠的應(yīng)用程序中起著關(guān)鍵作用,而AOP則可以幫助我們更好地管理和組織代碼,我們將深入研究如何結(jié)合AOP和異常處理來構(gòu)建健壯的應(yīng)用
    2023-09-09
  • Java 鏈表的定義與簡(jiǎn)單實(shí)例

    Java 鏈表的定義與簡(jiǎn)單實(shí)例

    這篇文章主要介紹了 Java 鏈表的定義與簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • java使用HttpSession實(shí)現(xiàn)QQ訪問記錄

    java使用HttpSession實(shí)現(xiàn)QQ訪問記錄

    這篇文章主要介紹了java使用HttpSession實(shí)現(xiàn)QQ的訪問記錄的相關(guān)資料,需要的朋友可以參考下
    2016-03-03

最新評(píng)論