自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試 ThreadLocal,被問(wèn)懵了?看完這篇文章你就穩(wěn)了!

開(kāi)發(fā) 前端
今天就和大家聊聊 ThreadLocal 這個(gè)面試高頻考點(diǎn),不僅讓你能答出基礎(chǔ)概念,還能講出實(shí)際使用場(chǎng)景,讓面試官對(duì)你刮目相看!

引言

小米最近在做社招面試,遇到了一位候選人,面試到 Java 并發(fā)時(shí),聊到了 ThreadLocal,候選人一開(kāi)始信心滿滿:“這個(gè)我會(huì)!” 結(jié)果,深挖幾輪之后,發(fā)現(xiàn)這位候選人只會(huì)皮毛,甚至踩了不少坑……

于是,今天就和大家聊聊 ThreadLocal 這個(gè)面試高頻考點(diǎn),不僅讓你能答出基礎(chǔ)概念,還能講出實(shí)際使用場(chǎng)景,讓面試官對(duì)你刮目相看!

什么是 ThreadLocal?

想象一下,你去健身房辦了一張私教卡,每次去健身房,教練都會(huì)給你專屬定制的訓(xùn)練計(jì)劃,而不會(huì)讓你去練別人的計(jì)劃。

ThreadLocal 就像這張 私教卡,它的核心作用就是:讓每個(gè)線程都能擁有自己的專屬變量,而不會(huì)影響到其他線程。

在 Java 代碼中,我們通常用 ThreadLocal 來(lái) 存儲(chǔ)每個(gè)線程獨(dú)有的數(shù)據(jù),避免線程之間的數(shù)據(jù)污染。來(lái)看一個(gè)最簡(jiǎn)單的例子:

圖片圖片

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

圖片圖片

每個(gè)線程都有自己獨(dú)立的 ThreadLocal 變量,即使修改了變量的值,也不會(huì)影響其他線程!

ThreadLocal 的工作原理

1. 底層數(shù)據(jù)結(jié)構(gòu)

ThreadLocal 的底層實(shí)現(xiàn)其實(shí)是 每個(gè)線程內(nèi)部維護(hù)一個(gè) ThreadLocalMap,這個(gè) Map 以 ThreadLocal 變量為 key,具體的值為 value。

簡(jiǎn)單來(lái)說(shuō),每個(gè)線程內(nèi)部都有一個(gè)類似這樣的數(shù)據(jù)結(jié)構(gòu):

圖片圖片

當(dāng)我們調(diào)用 threadLocal.set(value) 時(shí),數(shù)據(jù)并不會(huì)存儲(chǔ)到 ThreadLocal 對(duì)象本身,而是存放在 當(dāng)前線程的 ThreadLocalMap 里。

2. 內(nèi)存泄漏問(wèn)題

ThreadLocal 設(shè)計(jì)上是弱引用,但 ThreadLocalMap 里的 value 是強(qiáng)引用,如果不手動(dòng)清理 ThreadLocal.remove(),可能會(huì)導(dǎo)致內(nèi)存泄漏。來(lái)看一個(gè)坑:

圖片圖片

如果線程池中線程復(fù)用,ThreadLocal 沒(méi)有 remove(),線程的 ThreadLocalMap 可能無(wú)法被回收,從而導(dǎo)致內(nèi)存泄漏。

最佳實(shí)踐: 每次使用完 ThreadLocal,記得調(diào)用 remove(),防止內(nèi)存泄漏!

ThreadLocal 典型使用場(chǎng)景

1. 用戶身份信息存儲(chǔ)(常見(jiàn))

在 Web 應(yīng)用中,每個(gè)請(qǐng)求通常都有自己的 用戶身份信息,比如 登錄用戶 ID。我們可以用 ThreadLocal 來(lái)存儲(chǔ)用戶信息,保證在同一個(gè)線程的多個(gè)方法調(diào)用中,都能訪問(wèn)到當(dāng)前用戶的信息。

圖片圖片

使用方式:

圖片圖片

為什么要用 ThreadLocal?

因?yàn)?HTTP 請(qǐng)求是多線程并發(fā)的,如果使用全局變量存儲(chǔ) userId,會(huì)導(dǎo)致數(shù)據(jù)污染!但用 ThreadLocal,每個(gè)請(qǐng)求的 userId 只存儲(chǔ)在自己的線程中,互不影響。

2. 事務(wù)管理(數(shù)據(jù)庫(kù)連接)

在 Spring 的事務(wù)管理中,ThreadLocal 被用來(lái)存儲(chǔ) 數(shù)據(jù)庫(kù)連接,保證同一個(gè)事務(wù)中使用同一個(gè)數(shù)據(jù)庫(kù)連接。

圖片

3. 日志跟蹤(Tracing)

在分布式系統(tǒng)中,我們經(jīng)常需要給每個(gè)請(qǐng)求分配一個(gè)唯一的追蹤 ID(Trace ID),用來(lái)跟蹤整個(gè)請(qǐng)求的執(zhí)行流程。ThreadLocal 也是一個(gè)很好的選擇:

圖片圖片

然后在日志中加上 Trace ID:

圖片圖片

這樣,整個(gè)請(qǐng)求在不同的日志中都有相同的 Trace ID,方便排查問(wèn)題!

ThreadLocal 的優(yōu)缺點(diǎn)

圖片

總結(jié)

ThreadLocal 是 Java 并發(fā)中的 “線程局部變量”,常用于存儲(chǔ)線程獨(dú)有的數(shù)據(jù),避免線程間的數(shù)據(jù)污染。它的常見(jiàn)使用場(chǎng)景包括:

  • 用戶身份信息存儲(chǔ)
  • 事務(wù)管理(數(shù)據(jù)庫(kù)連接)
  • 日志追蹤(Tracing)

但使用時(shí)一定要注意內(nèi)存泄漏問(wèn)題,記得在適當(dāng)?shù)臅r(shí)機(jī)調(diào)用 remove() 方法。

責(zé)任編輯:武曉燕 來(lái)源: 軟件求生
相關(guān)推薦

2022-05-27 08:18:00

HashMapHash哈希表

2019-07-10 15:15:23

JVM虛擬機(jī)Java

2018-04-23 11:00:44

PythonRedisNoSQL

2024-11-19 18:03:04

2023-12-18 08:03:56

并發(fā)編程Java

2017-03-10 21:04:04

Android適配

2015-12-02 18:11:06

百度地圖/地圖軟件

2017-03-07 15:35:26

Android適配 界面

2020-11-12 10:37:29

微服務(wù)

2021-02-24 07:38:50

Redis

2017-08-09 15:07:08

大數(shù)據(jù)數(shù)據(jù)分析戶畫像

2021-10-14 06:36:38

存儲(chǔ)云存儲(chǔ)本地存儲(chǔ)

2022-02-18 06:56:18

Wi-Fi路由器局域網(wǎng)

2019-08-01 11:04:10

Linux磁盤I

2018-09-28 09:32:57

2020-01-09 15:30:32

微服務(wù)架構(gòu)互聯(lián)網(wǎng)

2017-09-08 11:10:35

前端面試Http協(xié)議

2020-02-08 16:46:29

微服務(wù)架構(gòu)復(fù)雜

2019-01-30 13:44:34

JVM內(nèi)存服務(wù)器

2017-06-01 18:55:44

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)