Netty中FastThreadLocal解讀

io.netty.util.concurrent.FastThreadLocal 是 Netty 中提供的高性能線程局部存儲(Thread-Local Storage)實現,位于 io.netty.util.concurrent 包。它是 Java 標準庫 ThreadLocal 的替代品,旨在優化性能,減少內存分配和訪問開銷,特別適合 Netty 的高并發異步框架。FastThreadLocal 依賴 io.netty.util.internal.InternalThreadLocalMap 實現高效存儲,廣泛用于 EventLoop、對象池(如 Recycler)、和性能敏感場景。


1. 源碼分析

FastThreadLocal 使用 InternalThreadLocalMap (請見https://blog.csdn.net/eclipseC/article/details/149756328?spm=1001.2014.3001.5501)的 indexedVariables 數組存儲線程局部變量,通過全局唯一的索引(由 InternalThreadLocalMap.nextVariableIndex() 分配)訪問。

源碼注釋

/*** FastThreadLocal 是 Netty 的高性能線程局部存儲實現,優于 Java 的 ThreadLocal。* 通過 InternalThreadLocalMap 的索引數組存儲變量,減少哈希表開銷。* 每個 FastThreadLocal 實例分配一個唯一索引,用于訪問線程局部變量。* @param <V> 線程局部變量的類型*/
public class FastThreadLocal<V> {/*** 分配唯一的索引,用于在 InternalThreadLocalMap 中存儲變量。*/private final int index = InternalThreadLocalMap.nextVariableIndex();/*** 獲取當前線程的線程局部變量值。* @return 變量值,如果未設置則調用 initialize 初始化*/public final V get() {return get(InternalThreadLocalMap.get()); // 獲取當前線程的 map}/*** 從指定的 InternalThreadLocalMap 獲取變量值。* @param threadLocalMap 當前線程的 InternalThreadLocalMap* @return 變量值,如果未設置則初始化*/@SuppressWarnings("unchecked")public final V get(InternalThreadLocalMap threadLocalMap) {Object v = threadLocalMap.indexedVariable(index); // 獲取索引處的值if (v != InternalThreadLocalMap.UNSET) { // 如果不是 UNSET,直接返回return (V) v;}return initialize(threadLocalMap); // 初始化并返回}/*** 設置當前線程的線程局部變量值。* @param value 要設置的值*/public final void set(V value) {if (value != InternalThreadLocalMap.UNSET) { // 避免設置 UNSETset(InternalThreadLocalMap.get(), value);} else {remove(); // 設置 UNSET 等同于移除}}/*** 在指定的 InternalThreadLocalMap 中設置變量值。* @param threadLocalMap 當前線程的 InternalThreadLocalMap* @param value 要設置的值*/public final void set(InternalThreadLocalMap threadLocalMap, V value) {if (value != InternalThreadLocalMap.UNSET) {if (threadLocalMap.setIndexedVariable(index, value)) { // 設置值addToVariablesToRemove(threadLocalMap, this); // 加入清理列表}} else {remove(threadLocalMap); // 移除變量}}/*** 移除當前線程的線程局部變量。*/public final void remove() {remove(InternalThreadLocalMap.get());}/*** 在指定的 InternalThreadLocalMap 中移除變量。* @param threadLocalMap 當前線程的 InternalThreadLocalMap*/@SuppressWarnings("unchecked")public final void remove(InternalThreadLocalMap threadLocalMap) {Object v = threadLocalMap.indexedVariable(index);if (v != InternalThreadLocalMap.UNSET) { // 如果變量存在threadLocalMap.setIndexedVariable(index, InternalThreadLocalMap.UNSET); // 設置為 UNSETremoveFromVariablesToRemove(threadLocalMap, this); // 從清理列表移除try {onRemoval((V) v); // 調用清理回調} catch (Exception e) {PlatformDependent.throwException(e);}}}/*** 初始化線程局部變量值。* @param threadLocalMap 當前線程的 InternalThreadLocalMap* @return 初始值*/protected V initialize(InternalThreadLocalMap threadLocalMap) {V v = null;try {v = initialValue(); // 調用子類的初始值方法} catch (Exception e) {PlatformDependent.throwException(e);}threadLocalMap.setIndexedVariable(index, v); // 設置初始值addToVariablesToRemove(threadLocalMap, this); // 加入清理列表return v;}/*** 提供默認的初始值,子類可重寫。* @return 默認返回 null* @throws Exception 如果初始化失敗*/protected V initialValue() throws Exception {return null;}/*** 當變量被移除時調用,子類可重寫以實現清理邏輯。* @param value 被移除的變量值* @throws Exception 如果清理失敗*/protected void onRemoval(@SuppressWarnings("UnusedParameters") V value) throws Exception {}
}

2. 作用與功能

FastThreadLocal 是 Netty 優化的線程局部存儲實現,其主要作用包括:

  1. 高性能存儲

    • 使用 InternalThreadLocalMapindexedVariables 數組,通過整數索引訪問變量,相比 Java ThreadLocalHashMap 實現,減少了哈希計算和沖突處理開銷。
    • 每個 FastThreadLocal 實例分配一個唯一索引(index),通過 InternalThreadLocalMap.nextVariableIndex() 生成。
  2. 線程隔離

    • 確保每個線程的變量獨立存儲,適合 Netty 的單線程 EventLoop 模型。
    • 配合 FastThreadLocalThread 進一步優化性能,減少 ThreadLocal 的訪問開銷。
  3. 支持清理機制

    • 提供 remove 方法和 onRemoval 回調,允許清理線程局部變量,防止內存泄漏。
    • 維護 variablesToRemove 列表,跟蹤需要清理的 FastThreadLocal 實例。
  4. 支持 Netty 功能模塊

    • 對象池(Recycler):存儲對象池的上下文數據,優化 ByteBuf 等對象的復用。
    • 上下文管理:在 EventLoopChannelPipeline 中存儲線程特定的狀態。
    • 性能優化:減少反射和內存分配,適用于高并發場景。

3. 關鍵方法解析

以下是 FastThreadLocal 的核心方法及其作用:

3.1 get
  • 簽名public final V get()
  • 作用:獲取當前線程的線程局部變量值。
  • 邏輯
    • 調用 InternalThreadLocalMap.get() 獲取當前線程的 InternalThreadLocalMap
    • 通過 indexindexedVariables 獲取值。
    • 如果值為 UNSET,調用 initialize 初始化。
  • 使用場景:獲取線程局部變量,如對象池中的 ByteBuf
3.2 set
  • 簽名public final void set(V value)
  • 作用:設置當前線程的線程局部變量值。
  • 邏輯
    • 如果 value != UNSET,設置值并加入清理列表。
    • 如果 value == UNSET,調用 remove 移除變量。
  • 使用場景:設置線程特定的上下文,如 Recycler 的對象池。
3.3 remove
  • 簽名public final void remove()
  • 作用:移除當前線程的線程局部變量。
  • 邏輯
    • 檢查變量是否為 UNSET,若不是,設置為 UNSET,從清理列表移除,并調用 onRemoval
  • 使用場景:清理不再需要的變量,防止內存泄漏。
3.4 initialize
  • 簽名protected V initialize(InternalThreadLocalMap threadLocalMap)
  • 作用:初始化線程局部變量值。
  • 邏輯
    • 調用 initialValue() 獲取默認值(子類可重寫)。
    • 設置值到 indexedVariables 并加入清理列表。
  • 使用場景:首次訪問變量時提供初始值。
3.5 initialValue
  • 簽名protected V initialValue() throws Exception
  • 作用:提供默認初始值,子類可重寫。
  • 默認實現:返回 null
  • 使用場景:自定義初始值,如初始化對象池的默認對象。
3.6 onRemoval
  • 簽名protected void onRemoval(V value) throws Exception
  • 作用:變量移除時的回調,子類可重寫以實現清理邏輯。
  • 使用場景:釋放資源,如對象池中的對象回收。

4. 與 InternalThreadLocalMap 的關系

FastThreadLocal 依賴 InternalThreadLocalMap 實現存儲:

  • 索引分配:每個 FastThreadLocal 實例通過 InternalThreadLocalMap.nextVariableIndex() 分配唯一索引,存儲在 indexedVariables 數組中。
  • 高效訪問
    • getset 方法通過索引直接訪問 indexedVariables,避免 ThreadLocal 的哈希表操作。
    • InternalThreadLocalMap.UNSET 標記未設置的槽位,區分 null 值。
  • 清理機制InternalThreadLocalMap 維護 variablesToRemove 列表,FastThreadLocalsetremove 方法更新該列表,確保變量可被清理。

5. 使用場景

FastThreadLocal 的主要應用場景包括:

  1. 對象池(Recycler)

    • 存儲線程局部的對象池上下文,優化 ByteBuf 等對象的復用。
    • 示例:
      private static final FastThreadLocal<Recycler.Handle> HANDLE = new FastThreadLocal<Recycler.Handle>() {@Overrideprotected Recycler.Handle initialValue() {return new Recycler.Handle();}
      };
      
  2. 上下文管理

    • EventLoopChannelPipeline 中存儲線程特定的狀態。
    • 示例:緩存 ChannelHandler 的處理狀態。
  3. 隨機數生成

    • 配合 InternalThreadLocalMaprandom 字段,提供線程局部的隨機數生成器。
    • 示例:負載均衡選擇 EventLoop
  4. 性能敏感場景

    • 在高并發場景中,FastThreadLocal 提供低開銷的線程局部變量訪問。
    • 示例:NioEventLoop 中存儲臨時 I/O 上下文。

6. 與 Java ThreadLocal 的對比

特性FastThreadLocalThreadLocal
存儲方式基于 InternalThreadLocalMap 的數組索引基于 ThreadLocalMap 的哈希表
性能高,索引訪問避免哈希計算較低,哈希表操作可能有沖突
線程支持優化 FastThreadLocalThread,兼容普通線程支持所有線程
清理機制提供 removeonRemoval 回調,防止泄漏需手動調用 remove,易泄漏
使用場景Netty 內部,如對象池、事件循環上下文通用線程局部存儲

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/91035.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/91035.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/91035.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

上海迪士尼游玩攻略 小鐵寄存柜讓你輕松暢玩

去上海迪士尼玩最煩帶一堆行李&#xff0c;其實有小鐵寄存柜幫忙就能輕裝上陣&#xff0c;各個關鍵位置都有分布&#xff0c;玩起來特別省心。?剛到迪士尼的時候&#xff0c;要是坐地鐵到上海國際旅游度假區站&#xff0c;1/2 號口安檢區就有小鐵柜&#xff0c;行李箱、大背包…

飛算科技重磅出品:飛算 JavaAI 重構 Java 開發效率新標桿

在 Java 開發領域&#xff0c;一款由國家級高新技術企業自主研發的智能工具正引發行業關注 —— 飛算 JavaAI 不僅承載著中國原創技術的創新基因&#xff0c;更以貼合實際開發場景的功能設計&#xff0c;成為眾多企業提升 Java 開發效率的核心助力。?作為飛算數智科技&#xf…

python案例:基于python 神經網絡cnn和LDA主題分析的旅游景點滿意度分析

1&#xff0e;緒論1.1研究背景與意義1.1.1研究背景隨著旅游業的快速發展&#xff0c;滿意度分析成為評估旅游景點質量和提升游客體驗的重要手段。作為中國的旅游城市之一&#xff0c;其旅游景點吸引了大量游客。然而&#xff0c;如何科學評估和提升旅游景點的滿意度&#xff0c…

Git快速入門,完整的git項目管理工具教程,git入門到精通!

Git的下載與安裝&#xff1a; 直接去官網下載即可&#xff1b; 或者查看這個博客學會下載:Git 詳細安裝教程&#xff08;詳解 Git 安裝過程的每一個步驟&#xff09;_git安裝-CSDN博客 注意&#xff1a;一個文件夾下只能有一個本地倉庫(就是一個.git) 細節操作

C++day07(三種取整方法)

學習目標 認識流程圖 多種方式解決問題 取整方式和取整函數 1.解決編程問題的過程 1.理解題意,找出關鍵信息。 2.整理思路,用圖或者文字寫出算法。 3.將算法步驟翻譯為C++代碼。 4.編譯運行,修改語法或邏輯錯誤。 不符合則需要回到上一步進行修改。 5 .輸入測試用例與…

Go語言實戰案例-LRU緩存機制模擬

在高性能服務開發中&#xff0c;緩存是提升訪問速度和減少后端負載的重要手段。常見的緩存淘汰策略中&#xff0c;**LRU&#xff08;Least Recently Used&#xff0c;最近最少使用&#xff09;**是應用最廣的一種。本篇我們用Go語言手寫一個LRU緩存機制的模擬實現。一、LRU緩存…

vue2中實現leader-line-vue連線文章對應字符

效果展示 通過點擊右邊的tag,觸發連接操作 第一步:獲取右邊tag展示 1.右邊的tag列表展示,我這邊是分為兩個list嵌套的數據結構; {"人員": [{

SPEA2(Strength Pareto Evolutionary Algorithm 2)優化算法簡介

前言 提醒&#xff1a; 文章內容為方便作者自己后日復習與查閱而進行的書寫與發布&#xff0c;其中引用內容都會使用鏈接表明出處&#xff08;如有侵權問題&#xff0c;請及時聯系&#xff09;。 其中內容多為一次書寫&#xff0c;缺少檢查與訂正&#xff0c;如有問題或其他拓展…

IDEA 手動下載安裝數據庫驅動,IDEA無法下載數據庫驅動問題解決方案,IDEA無法連接數據庫解決方案(通用,Oracle為例)

一、查詢要下載的數據庫驅動 在IDEA側邊欄找到數據庫&#xff08;databases&#xff09;&#xff0c;新增一個數據連接 右鍵&#xff0c;屬性 點擊下載&#xff0c;查看要下載的驅動版本 二、下載數據庫驅動&#xff08;Oracle為例&#xff09; 下載對應MySQL/Oracle數據庫的…

專業Python爬蟲實戰教程:逆向加密接口與驗證碼突破完整案例

案例背景假設我們需要爬取一家內部測試系統的動態數據API接口。該系統前端頁面使用了復雜的JavaScript混淆技術來防止接口被直接調用&#xff0c;同時對請求參數進行了加密簽名。另外&#xff0c;登錄環節帶有圖形驗證碼用于防護。我們的目標是&#xff1a;分析JavaScript代碼&…

【SQL】Windows MySQL 服務查詢啟動停止自啟動(保姆級)

MySQL是一種開放源代碼的輕量級關系型數據庫管理系統&#xff0c;使用最常用的結構化查詢語言&#xff08;SQL&#xff09;對數據庫進行管理。由于MySQL具有體積小、速度快、成本低、開放源碼等優點&#xff0c;現已被廣泛應用于互聯網上的中小型網站中&#xff0c;并且大型網站…

算法提升之數論(矩陣+快速冪)

通過矩陣和快速冪的方法來解決算法題目可以很好地降低時間復雜度&#xff0c;幫助大家更好地解決題目。下面這道題目有一定難度&#xff0c;希望大家可以好好地理解&#xff0c;相信對大家會有很大的幫助。問題描述有 n(2≤n≤10) 個玩家玩游戲&#xff0c;他們按 1 到 n 編號。…

數學建模算法-day[14]

6.2 傳染病預測問題 問題提出 世界上存在很多傳染病&#xff0c;如何根據其傳播機理預測疾病得傳染范圍及染病人數等&#xff0c;對傳染病的控制意義十分重大。 1.指數傳播模型 基本假設 (1) 所研究的區域是一封閉區域&#xff0c;在一個時期內人口總量相對穩定&#xff0c;不考…

Linux救援模式之簡介篇

什么是救援模式&#xff1f;救援模式提供了一個最小的Linux環境&#xff0c;通常只加載最基本的系統組件&#xff0c;允許管理員&#xff1a;修復損壞的系統恢復丟失的文件修改配置文件重置密碼檢查磁盤錯誤重新安裝引導加載程序如何進入救援模式&#xff1f;1. 通過GRUB菜單進…

C++20實戰FlamingoIM開發

C++20 與 Flamingo IM 實例 C++20 引入了許多新特性,如概念(Concepts)、協程(Coroutines)、范圍(Ranges)等。Flamingo IM 是一個即時通訊項目,結合 C++20 的特性可以提升代碼的可讀性和性能。以下是基于 C++20 和 Flamingo IM 的實例。 協程實現異步網絡通信 使用 C…

FPGA實現SRIO高速接口與DSP交互,FPGA+DSP異構方案,提供3套工程源碼和技術支持

目錄1、前言&#xff1a;SRIO在FPGADSP架構中的作用工程概述免責聲明2、相關方案推薦我已有的所有工程源碼總目錄----方便你快速找到自己喜歡的項目我這里已有的FPGADSP異構方案我這里已有的 GT 高速接口解決方案3、工程詳細設計方案工程設計原理框圖FPGA端工程源碼FPGA端SRIO從…

記一次導出pdf表單引發的問題

需求&#xff1a;點擊按鈕&#xff0c;將相關內容生成pdf下載下來問題1&#xff1a;之前項目封裝好的下載文件方法不攜帶token 我嘗試新寫了一個方法&#xff0c;攜帶token問題2&#xff1a;此時出現了跨域問題 我分別嘗試在controller類上和方法上加CrossOrigin(origins “*”…

AI-調查研究-39-多模態大模型量化 微調與量化如何協同最大化性能與效率?

點一下關注吧&#xff01;&#xff01;&#xff01;非常感謝&#xff01;&#xff01;持續更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持續更新中&#xff01;&#xff08;長期更新&#xff09; AI煉丹日志-30-新發布【1T 萬億】參數量大模型&#xff01;Kim…

基于Dify構建本地化知識庫智能體:從0到1的實踐指南

技術選型與方案設計 在企業級AI應用落地中&#xff0c;本地化知識庫智能體已成為提升業務效率的核心工具。Dify作為低代碼AI應用開發平臺&#xff0c;結合RAG&#xff08;檢索增強生成&#xff09;技術&#xff0c;可快速構建私有化智能問答系統。以下是關鍵技術選型與架構設計…

C++與C#實戰:FFmpeg屏幕錄制開發指南

基于FFmpeg使用C#和C++開發 以下是一些基于FFmpeg使用C#和C++開發的簡單屏幕錄制軟件示例,涵蓋不同平臺和功能需求。這些示例可作為學習或項目開發的起點。 使用C++開發FFmpeg屏幕錄制 基礎屏幕錄制(Windows) #include <libavcodec/avcodec.h> #include <libav…