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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…