成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

反問面試官三個 ThreadLocal 的問題

開發
ThreadLocal? 是并發編程中的強大工具,能夠為每個線程提供獨立的變量副本,避免線程安全問題。

ThreadLocal,一個Java人面試繞不開的話題,我也很奇怪為什么那些面試官很喜歡問這個,也不知道他們自己有沒有搞清楚。

接下來,我想先說說ThreadLocal的用法和使用場景,然后反問面試官3個關于ThreadLocal的話題。

使用方法和場景

一句話總結:ThreadLocal是給每個線程準備一份“獨立的小空間”,它讓每個線程都擁有自己獨立的變量副本。在多個線程并發訪問時,不用擔心變量之間的沖突問題,避免了多線程之間的數據共享風險。

1.使用場景

ThreadLocal的使用場景主要在多線程環境中,能夠為每個線程提供獨立的變量副本。比如:

  • 用戶上下文信息:比如,在Web應用中,每個請求可能由不同的線程處理,在處理用戶請求時為每個線程維護獨立的用戶信息。
  • 數據庫連接管理:比如,在多線程環境下,每個線程需要有自己獨立的數據庫連接。
  • 事務管理:比如,在處理事務時,每個線程可能需要有自己的事務上下文,確保線程安全的事務操作。
  • 數據傳遞:比如,同一個線程,在不同的方法之間傳遞數據,但又不想使用方法參數去傳遞,就可以使用ThreadLocal。像我們常用的日志跟蹤場景,跟蹤的ID會存在ThreadLocal中貫穿整個鏈條。

總之有2個場景:

  • 在多線程場景下,每個線程需要獨立管理變量的場景。
  • 某個線程想在整條鏈路上共享獨立變量的場景。

2.使用方法

使用時,記住3條核心原則:

  • 每個線程都有一份獨立的數據。
  • 線程內部使用的是ThreadLocalMap來保存數據,Key就是ThreadLocal對象。
  • 使用完畢后,記得調用remove方法,防止內存溢出。

代碼示例

獨立保存變量的示例:

public class ThreadLocal4Independent {

    private static ThreadLocal<Integer> threadLocalVar = new ThreadLocal<>();

    public static void main(String[] args) {
        Runnable task = () -> {
            int num = (int) (Math.random() * 100);
            threadLocalVar.set(num);
            System.out.println("線程:" + Thread.currentThread().getName() + "的值:" + threadLocalVar.get());
            threadLocalVar.remove();
        };

        new Thread(task, "1").start();
        new Thread(task, "2").start();
    }

}

傳遞參數的示例:

public class ThreadLocal4DataPass {
    // 使用ThreadLocal來存儲需要在多個方法間傳遞的數據
    private static final ThreadLocal<String> threadLocalData = new ThreadLocal<>();

    public static void main(String[] args) {
        // 在主線程中設置數據
        threadLocalData.set("ThreadLocal");

        // 在主線程中調用不同的方法
        method1();
        method2();
        
        // 清除ThreadLocal變量,防止內存泄露
        threadLocalData.remove();
    }

    private static void method1() {
        // 在method1中獲取數據并打印
        String data = threadLocalData.get();
        System.out.println("方法1拿到的數據是:" + data);
    }

    private static void method2() {
        // 在method2中獲取數據并打印
        String data = threadLocalData.get();
        System.out.println("方法2拿到的數據是:" + data);
    }
}

聊完使用場景和方法,接下來問面試官幾個問題。

問題1:請畫出ThreadLocal和Thread的關系圖

ThreadLocal和Thread的關系圖如下。

這里要牢記3點:

(1) 數據實際上是存在ThreadLocalMap中的,ThreadLocalMap歸Thread所持有。見源代碼。

(2) ThreadLocalMap內部使用的是K-V結構,Key是我們定義的ThreadLocal對象。見源代碼。

(3) ThreadLocalMap對ThreadLocal是弱引用關系。見源代碼。

問題2:為什么ThreadLocalMap里的Key是弱引用

那為什么ThreadLocalMap里的Key是使用ThreadLocal呢?為什么又是弱引用呢?

這就不得不說JDK的設計者的思想非常精妙了,有3點妙處:

  • 一個線程要是存了多種數據,總得有個規則去找他們,那就根據定義的ThreadLocal對象去找吧。
  • 對于開發者來說,他只需要使用ThreadLocal去保存數據即可,無需關系底層結構。也就是說對外暴露簡單的使用方式即可,對于不需要調用方知道的細節全部隱藏。
  • 一般情況下Thread的生命周期會很長,比如Web容器啟動后,就會啟動大量的線程丟到線程池中復用。所以ThreadLocalMap的生命周期也會很長。但是,ThreadLocal對象存在的周期不一定長,如果,ThreadLocalMap的Key對ThreadLocal是強引用的話,那么ThreadLocal對象就會一直存在于內存中得不到釋放,最終會導致內存溢出,所以采用了弱引用。

問題3:為什么ThreadLocal使用不當會造成內存溢出

從上圖的關系圖可以看出,Value的生命周期是跟著Thread的生命周期來的,如果一直不處理的話,也會出現內存溢出的情況。

為了避免內存溢出的情況,我們在使用完ThreadLocal后,要即使調用remove方法,以便JVM回收Value。

總結

ThreadLocal 是并發編程中的強大工具,能夠為每個線程提供獨立的變量副本,避免線程安全問題。并且這個ThreadLocal存入的值能夠貫穿整個流程。使用時要注意上文的幾點,防止造成內存溢出。

責任編輯:趙寧寧 來源: 程序員半支煙
相關推薦

2024-09-29 16:17:02

2024-11-11 10:40:19

Java變量副本

2022-10-25 10:20:31

線程變量原理

2020-06-16 14:52:41

面試官模型遞歸

2020-10-05 21:46:54

線程

2022-11-04 08:47:52

底層算法數據

2024-03-13 07:53:57

弱引用線程工具

2020-04-20 08:35:48

HTTP HTTPS網絡協議

2015-08-13 10:29:12

面試面試官

2021-08-10 08:34:12

Git ForkBranch

2019-03-06 14:26:31

Javascript面試前端

2025-03-18 12:00:00

閉包JavaScript前端

2021-05-07 18:12:32

ThreadLocal面試項目

2025-02-19 00:00:00

RabbitMQTTL插件

2010-08-23 15:06:52

發問

2022-05-23 08:43:02

BigIntJavaScript內置對象

2024-11-22 08:31:32

Redis數據持久化高可用

2020-04-09 13:38:40

MySQL數據庫臟讀

2010-08-12 16:28:35

面試官

2021-01-06 08:34:21

Spring核心組件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美a级成人淫片免费看 | 日日骚网 | 黄频视频 | jizz视频| 青草青草久热精品视频在线观看 | 国产亚洲成av人在线观看导航 | 亚洲成人一区 | 日日碰碰| 亚洲精品大片 | 国产清纯白嫩初高生在线播放视频 | 成人欧美一区二区三区 | 久久亚洲一区二区三区四区 | 久久成人国产 | 久久亚洲一区 | 黄a大片| 精品九九 | 91精品国产日韩91久久久久久 | 一级黄a视频 | 狠狠狠色丁香婷婷综合久久五月 | 亚洲麻豆 | 最近中文字幕免费 | 综合一区二区三区 | 欧美黄色片在线观看 | 久久999| 久久精品久久久久久 | 青青久久 | 日批的视频 | 国产精品久久久久久久久久久久久久 | 久久不卡 | 久久精品视频免费观看 | 亚洲成人日韩 | 日韩在线免费视频 | 国产欧美一区二区三区在线看 | 亚洲超碰在线观看 | 国产一区二区三区高清 | 四虎永久免费影院 | 最新中文字幕在线 | 3p视频在线观看 | 欧美又大粗又爽又黄大片视频 | 99这里只有精品视频 | 日韩视频在线播放 |