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

談談你對ThreadLocal的理解

開發 前端
ThreadLocal是多線程中對于解決線程安全的一個操作類,它會為每個線程都分配一個獨立的線程副本從而解決了變量并發訪問沖突的問題。ThreadLocal 同時實現了線程內的資源共享。


圖片

思考:對ThreadLocal的理解多少?

springboot葵花寶典

主要分享JAVA技術,主要包含SpringBoot、SpingCloud、Docker、中間件等技術,以及Github開源項目

1.ThreadLocal概述

ThreadLocal是多線程中對于解決線程安全的一個操作類,它會為每個線程都分配一個獨立的線程副本從而解決了變量并發訪問沖突的問題。ThreadLocal 同時實現了線程內的資源共享

案例:使用JDBC操作數據庫時,會將每一個線程的Connection放入各自的ThreadLocal中,從而保證每個線程都在各自的 Connection 上進行數據庫的操作,避免A線程關閉了B線程的連接。

圖片圖片

2. ThreadLocal的實現原理&源碼解析

ThreadLocal本質來說就是一個線程內部存儲類,從而讓多個線程只操作自己內部的值,從而實現線程數據隔離

每個線程內有一個 ThreadLocalMap 類型的成員變量,用來存儲資源對象

圖片圖片

ThreadLocalMap 的一些特點

key 的 hash 值統一分配

初始容量 16,擴容因子 2/3,擴容容量翻倍

key 索引沖突后用開放尋址法解決沖突

2.1. ThreadLocal基本使用

set(value) 設置值:  以 ThreadLocal 自己作為 key,資源對象作為 value,放入當前線程的 ThreadLocalMap 集合中

get() 獲取值: 以 ThreadLocal 自己作為 key,到當前線程中查找關聯的資源值

remove() 清除值: 以 ThreadLocal 自己作為 key,移除當前線程關聯的資源值

代碼案例

public class ThreadLocalTest {
    static ThreadLocal<String> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) {
        new Thread(() -> {
            String name = Thread.currentThread().getName();
            threadLocal.set("zbbmeta");
            print(name);
            System.out.println(name + "-after remove : " + threadLocal.get());
        }, "t1").start();
        new Thread(() -> {
            String name = Thread.currentThread().getName();
            threadLocal.set("zbbmeta");
            print(name);
            System.out.println(name + "-after remove : " + threadLocal.get());
        }, "t2").start();
    }

    static void print(String str) {
        //打印當前線程中本地內存中本地變量的值
        System.out.println(str + " :" + threadLocal.get());
        //清除本地內存中的本地變量
        threadLocal.remove();
    }

}

3. ThreadLocal-內存泄露問題

在介紹內存泄露問題問題之前先介紹一下Java對象中的四種引用類型:Java對象中的四種引用類型:

  • 強引用: 最為普通的引用方式,表示一個對象處于有用且必須的狀態,如果一個對象具有強引用,則GC并不會回收它。即便堆中內存不足了,寧可出現OOM,也不會對其進行回收
Object obj = new Object();
  • 軟引用:軟引用用于描述一些還有用但并非必須保持的對象。在系統即將發生內存溢出之前,垃圾收集器會清理這些軟引用指向的對象
Object obj = new Object();
SoftReference<Object> softRef = new SoftReference<>(obj);
  • 弱引用:表示一個對象處于可能有用且非必須的狀態。在GC線程掃描內存區域時,一旦發現弱引用,就會回收到弱引用相關聯的對象。對于弱引用的回收,無關內存區域是否足夠,一旦發現則會被回收
Object obj = new Object();
WeakReference<Object> weakRef = new WeakReference<>(obj);
  • 虛引用:虛引用也稱為幽靈引用,它幾乎沒有實際意義,主要用于跟蹤對象被垃圾收集的活動;虛引用不能單獨使用,必須與引用隊列(ReferenceQueue)一起使用。當垃圾收集器準備回收一個對象時,如果發現它有虛引用,會把這個虛引用加入到與之關聯的引用隊列中
Object obj = new Object();
PhantomReference<Object> phantomRef = new PhantomReference<>(obj, referenceQueue);

3.1. ThreadLocal-內存泄露問題

每一個Thread維護一個ThreadLocalMap,在ThreadLocalMap中的Entry對象繼承了WeakReference,其中key為使用弱引用的ThreadLocal實例,value為線程變量的副本

圖片圖片

ThreadLocalMap 中的 key 被設計為弱引用,原因如下

Thread 可能需要長時間運行(如線程池中的線程),如果 key 不再使用,需要在內存不足(GC)時釋放其占用的內存

內存釋放時機

  • 被動 GC 釋放 key

僅是讓 key 的內存釋放,關聯 value 的內存并不會釋放

  • 懶惰被動釋放 value
  • get key 時,發現是 null key,則釋放其 value 內存
  • set key 時,會使用啟發式掃描,清除臨近的 null key 的 value 內存,啟發次數與元素個數,是否發現 null key 有關
  • 主動 remove 釋放 key,value
  • 會同時釋放 key,value 的內存,也會清除臨近的 null key 的 value 內存
  • 推薦使用它,因為一般使用 ThreadLocal 時都把它作為靜態變量(即強引用),因此無法被動依靠 GC 回收

4. ThreadLocal面試題

面試官:談談你對ThreadLocal的理解

候選人:

ThreadLocal 主要功能有兩個:

  • 第一個是可以實現資源對象的線程隔離,讓每個線程各用各的資源對象,避免爭用引發的線程安全問題
  • 第二個是實現了線程內的資源共享

面試官:好的,那你知道ThreadLocal的底層原理實現嗎?

候選人:

在ThreadLocal內部維護了一個一個 ThreadLocalMap 類型的成員變量,用來存儲資源對象

當我們調用 set 方法,就是以 ThreadLocal 自己作為 key,資源對象作為 value,放入當前線程的 ThreadLocalMap 集合中

當調用 get 方法,就是以 ThreadLocal 自己作為 key,到當前線程中查找關聯的資源值

當調用 remove 方法,就是以 ThreadLocal 自己作為 key,移除當前線程關聯的資源值

面試官:好的,那關于ThreadLocal會導致內存溢出這個事情,了解嗎?

候選人:

是應為ThreadLocalMap 中的 key 被設計為弱引用,它是被動的被GC調用釋放key,不過關鍵的是只有key可以得到內存釋放,而value不會,因為value是一個強引用。

在使用ThreadLocal 時都把它作為靜態變量(即強引用),因此無法被動依靠 GC 回收,建議主動的remove 釋放 key,這樣就能避免內存溢出。


責任編輯:武曉燕 來源: springboot葵花寶典
相關推薦

2022-06-30 09:10:33

NoSQLHBaseRedis

2022-09-19 07:57:59

云服務互聯網基礎設施

2024-09-20 05:46:00

2024-09-11 16:49:55

2022-08-14 07:14:50

Kafka零拷貝

2022-10-09 15:18:31

SwaggerOpenAPI工具

2022-09-09 10:15:06

OAuthJava

2022-03-21 09:05:18

volatileCPUJava

2024-10-24 16:14:43

數據傳輸CPU零拷貝

2025-03-21 00:00:05

Reactor設計模式I/O 機制

2022-08-26 00:21:44

IO模型線程

2024-12-06 14:34:00

Spring過濾器

2025-03-07 00:11:00

JWTJSONSession

2024-09-27 15:43:52

零拷貝DMAIO

2025-02-21 15:25:54

虛擬線程輕量級

2022-09-06 11:13:16

接口PipelineHandler

2022-09-23 11:00:27

KafkaZookeeper機制

2022-06-10 11:51:49

MySQL事務隔離

2024-08-27 12:36:33

2022-08-26 00:02:03

RocketMQ單體架構MQ
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 999久久久| 成人一区二区三区在线观看 | 日韩在线免费播放 | 免费在线观看一区二区三区 | 亚洲专区在线 | 伊人伊人网 | 91在线看| 国产精品久久一区二区三区 | 久久精品国产一区二区电影 | 激情五月婷婷综合 | 成人免费看 | a级黄色毛片免费播放视频 国产精品视频在线观看 | 亚洲高清在线 | 欧美极品一区二区 | 欧美8一10sex性hd | 欧美日韩综合一区 | 99视频免费在线 | 成人精品一区二区户外勾搭野战 | 日日夜夜视频 | 91精品国产综合久久久久久丝袜 | 欧美成人综合 | 91在线视频在线观看 | 久久精品亚洲欧美日韩精品中文字幕 | 日韩欧美一二三区 | 精品国产久| 欧美成人精品一区二区男人看 | 成人日韩av| 一区二区三区回区在观看免费视频 | 国产精品99久久久久久人 | 国产欧美精品一区二区 | 国产精品久久久久久久久免费樱桃 | 成人在线小视频 | 亚洲高清成人 | 伊人激情网 | 自拍视频国产 | 激情五月综合 | 久草精品视频 | 日本一区二区在线视频 | 天堂中文字幕av | 久久精品国产99国产 | 久久成 |