当前位置: 首页 > news >正文

FastThreadLocal 原理解析

FastThreadLocal

fastthreadlocal

  1. 每个 FastThread 包含一个 FastThreadLocalMap,每个 FastThreadLocalThread 中的多个 FastThreadLocal 占用不同的索引。
  2. 每个 InternalThreadLocalMap 的第一个元素保存了所有的 ThreadLocal 对象。之后的元素保存了每个 ThreadLocal 对应的 value

基本操作

get()

当前线程中

  1. 找到 ThreadLocal 的 index,value 加入 InternalThreadLocalMap 对应索引的位置

set()

当前线程中

  1. 找到 ThreadLocal 的 index,value 加入 InternalThreadLocalMap 对应索引的位置
  2. 将 ThreadLocal 加入当前线程 InternalThreadLocalMap 的第一个元素对应的集合

remove()

当前线程中

  1. 找到 ThreadLocal 的 index,InternalThreadLocalMap 中 index 对应的 value 置为 UNSET
  2. 将 ThreadLocal 从当前线程 InternalThreadLocalMap 的第一个元素集合中删除

关键设计点

兼容 ThreadLocal

当线程没有使用 FastThreadLocal 的时候,默认走 ThreadLocal 的逻辑。

初始大小

初始大小为 32

hash 算法

直接使用全局的自增,不存在Hash 冲突,以空间换时间

扩容条件是什么?如何扩容?

  • 扩容条件:当前线程元素超出容量
  • 扩容:元素数量扩展为向上取最近 2 次幂整数,比如,5 取8,31 取 64。
    public boolean setIndexedVariable(int index, Object value) {Object[] lookup = indexedVariables;// index 大于容量if (index < lookup.length) {Object oldValue = lookup[index];lookup[index] = value;return oldValue == UNSET;} else {// 扩容expandIndexedVariableTableAndSet(index, value);return true;}}private void expandIndexedVariableTableAndSet(int index, Object value) {Object[] oldArray = indexedVariables;final int oldCapacity = oldArray.length;int newCapacity;// 当小于 2的30次方时,容量扩展为向上取最近 2 次幂整数,比如,5 取8,31 取 64。if (index < ARRAY_LIST_CAPACITY_EXPAND_THRESHOLD) {newCapacity = index;newCapacity |= newCapacity >>>  1;newCapacity |= newCapacity >>>  2;newCapacity |= newCapacity >>>  4;newCapacity |= newCapacity >>>  8;newCapacity |= newCapacity >>> 16;newCapacity ++;} else {newCapacity = ARRAY_LIST_CAPACITY_MAX_SIZE;}Object[] newArray = Arrays.copyOf(oldArray, newCapacity);Arrays.fill(newArray, oldCapacity, newArray.length, UNSET);newArray[index] = value;indexedVariables = newArray;}

如何防止内存泄漏

自动: 使用ftlt执行一个被FastThreadLocalRunnable wrap的Runnable任务,在任务执行完毕后会自动进行ftl的清理。

final class FastThreadLocalRunnable implements Runnable {private final Runnable runnable;private FastThreadLocalRunnable(Runnable runnable) {this.runnable = ObjectUtil.checkNotNull(runnable, "runnable");}@Overridepublic void run() {try {runnable.run();} finally {FastThreadLocal.removeAll();}}static Runnable wrap(Runnable runnable) {return runnable instanceof FastThreadLocalRunnable ? runnable : new FastThreadLocalRunnable(runnable);}
}

手动: ftl和InternalThreadLocalMap都提供了remove方法,在合适的时候用户可以(有的时候也是必须,例如普通线程的线程池使用ftl)手动进行调用,进行显示删除。

使用

final class FastThreadLocalRunnable implements Runnable {private final Runnable runnable;private FastThreadLocalRunnable(Runnable runnable) {this.runnable = (Runnable)ObjectUtil.checkNotNull(runnable, "runnable");}public void run() {try {this.runnable.run();} finally {// 如果用的是 FastThreadLocalRunnable ,默认会做清理FastThreadLocal.removeAll();}}static Runnable wrap(Runnable runnable) {return (Runnable)(runnable instanceof FastThreadLocalRunnable ? runnable : new FastThreadLocalRunnable(runnable));}
}

存在什么问题

1、空间浪费,所有线程的 ThreadLocalMap 数组大小是一样的
比如,线程1 创建 100 个 ThreadLocal 对象。线程 1 里面有一个长度为 100 的数组。
此时,第二个线程需要调用 ThreadLocal 100 的 get 方法,第二个线程需要分配 100 个 Object 对象。

import io.netty.util.concurrent.FastThreadLocal;
import io.netty.util.concurrent.FastThreadLocalThread;import java.util.ArrayList;
import java.util.List;public class FastThreadLocalTest {private List<FastThreadLocal<String>> fastThreadLocals = new ArrayList<>();private List<ThreadLocal<String>> threadLocals = new ArrayList<>();void thread1Init() {new Thread (() -> {for (int i = 0; i < 31; i++) {ThreadLocal<String> threadLocal = new ThreadLocal<>();threadLocal.get();threadLocals.add(threadLocal);}}).start();}void thread2Init() {new Thread(() -> {threadLocals.get(threadLocals.size() - 1).get();});}void fastThread1Init() {new FastThreadLocalThread (() -> {for (int i = 0; i < 33; i++) {FastThreadLocal<String> fastThreadLocal = new FastThreadLocal<>();fastThreadLocal.get();fastThreadLocals.add(fastThreadLocal);}}).start();}void fastThread2Init() {new FastThreadLocalThread(() -> {fastThreadLocals.get(fastThreadLocals.size() - 1).get();});}public static void main(String[] args) {FastThreadLocalTest test = new FastThreadLocalTest();test.fastThread1Init();test.fastThread2Init();test.thread1Init();test.thread2Init();}
}

2、FastThreadLocal 需要配套 FastThreadLocalThread 使用,不然还不如原生 ThreadLocal。
3、FastThreadLocal 使用最好配套 FastThreadLocalRunnable,这样执行完任务后会主动调用 removeAll 来移除所有

性能压测

netty 官方 mincrobench

相关文章:

FastThreadLocal 原理解析

FastThreadLocal 每个 FastThread 包含一个 FastThreadLocalMap&#xff0c;每个 FastThreadLocalThread 中的多个 FastThreadLocal 占用不同的索引。每个 InternalThreadLocalMap 的第一个元素保存了所有的 ThreadLocal 对象。之后的元素保存了每个 ThreadLocal 对应的 value …...

设计模式B站学习(一)(java)

这里写目录标题 一、设计模式概述1.1 软件设计模式的产生背景1.2 软件设计模式的概念1.3 学习设计模式的必要性1.4 设计模式分类 二、UML图2.1 类图概述2.2 类图的作用2.3 类图表示法2.3.1 类图表示方法2.3.2 类与类之间关系的表示方法2.3.2.1 关联关系2.3.2.2 聚合关系2.3.2.3…...

Pandas如何轻松按位置删除多重索引列?

在Pandas处理DataFrame数据的过程中&#xff0c;我们常常需要删除某些不需要的列。那么&#xff0c;如何高效地按位置删除Pandas DataFrame的多重索引列呢? 今天分享在Pandas中按位置删除多重索引列的具体方法: 第一步:获取所有列标签 使用df.columns获取DataFrame的所有列标…...

第五十七天学习记录:C语言进阶:结构体链表的自学

先展示一段代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h> #include <stdlib.h>// 定义链表节点结构体 typedef struct Node {int value;struct Node* next; } Node;int main() {// 创建链表头指针Node* head (Node*)malloc(sizeof(Node…...

【一次调频】考虑储能电池参与一次调频技术经济模型的容量配置方法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

ICV报告: 智能座舱SoC全球市场规模预计2025年突破50亿美元

在智能化、互联化车辆需求不断增加的推动下&#xff0c;汽车行业正在经历一场范式转变。这一转变的前沿之一是智能座舱SoC。本市场研究报告对智能座舱SoC市场进行了全面的分析&#xff0c;包括其应用领域、当前状况和主要行业参与者。 智能座舱SoC指的是现代汽车智能座舱系统的…...

在can协议的基础下编写DBC文件,然后使用该DBC文件下发can协议到底盘完整流程

目录 前言一、VectorCANdb下载及安装二、DBC文件的编写1.新建dbc文件2.建立dbc2.1根据CAN协议设置以下的signals2.2设置报文2.3建立报文与信号的关系2.4建立节点 三、编写程序使用UDP通信下发can协议1.查看can口、电脑ip以及端口号2.编写测试程序 前言 最近完成了一个项目&…...

工业传感器有哪些?

工业传感器是指能在工业制造过程能将感受的力、热、光、磁、声、湿、电、环境等被测量转换成电信号输出的器件与装置&#xff0c;在各种化工、机械、汽车等工业场景上都有应用。 工业传感器有哪些&#xff1f; 工业传感器由于不同的特性也被分为多种不同的类别&#xff0c;主要…...

Docker应用部署之Nginx

部署nginx 要求&#xff1a;在docker容器中部署nginx&#xff0c;并通过外部机器访问nginx 步骤&#xff1a; 1.搜索nginx镜像 docker search nginx 2.拉取nginx镜像 docker pull nginx 3.创建容器 #在root目录下创建nginx目录用于存放nginx项目 mkdir ~/nginx cd ~/ng…...

TerminalWorks TSPrint/TSScan/TSWebCam Crack

/ 远程桌面打印软件&#xff0c;TerminalWorks TSPrint Server/Client 从远程服务器打印到本地打印机的 简单方法 TSPrint 为您提供了一个简单的远程桌面打印软件&#xff0c;以及使 Windows 终端服务操作更容易的附加工具。有选择地启用或禁用功能&#xff0c;以便您可以完全…...

如何使用Springboot实现文件上传和下载,并为其添加实时进度条的功能

文件上传和下载是Web开发中非常基础的功能&#xff0c;但在实际开发中&#xff0c;我们经常需要实时显示文件上传或下载的进度。这篇文章将介绍如何使用Springboot实现文件上传和下载&#xff0c;并为其添加实时进度条的功能。 文件上传 添加Maven依赖项 首先&#xff0c;我…...

安装并新建windows下wxwroks7.0 bootrom工程

双击steup.exe 直接next 直接next 选择typical&#xff0c;然后next I accept 安装完成finish 现在双击Workbench 4&#xff0c;新建vxworks7.0工程&#xff0c;会出现下面的情况&#xff0c;因为没有licence 安装licence&#xff0c;将zwrsLicense-vx7-perm.lic粘贴到安装目…...

element-ui表格el-table的使用

先给大家展示一下效果 Table 属性 属性名说明类型可选值默认值data显示的数据array——heightTable 的高度&#xff0c; 默认为自动高度。 如果 height 为 number 类型&#xff0c;单位 px&#xff1b;如果 height 为 string 类型&#xff0c;则这个高度会设置为 Table 的 sty…...

Backtrader官方中文文档:第八章Indicators指标

本文档参考backtrader官方文档,是官方文档的完整中文翻译,可作为backtrader中文教程、backtrader中文参考手册、backtrader中文开发手册、backtrader入门资料使用。 Indicators指标章节目录 指标(Indicator)指标的使用__init__ 对比 next指标在`__init__`阶段的执行过程指标在…...

CAP原则

CAP原则又称CAP定理&#xff0c;指的是在一个分布式系统中&#xff0c;存在Consistency&#xff08;一致性&#xff09;、Availability&#xff08;可用性&#xff09;、Partition tolerance&#xff08;分区容错性&#xff09;&#xff0c;三者不可同时保证&#xff0c;最多只…...

【PowerQuery】M语言的使用产品和使用场景

当然PowerQuery的M语言应用场景不只是引用在PowerBI和Excel中,它具有广泛的应用场景。目前我们可以在以下产品的使用场景中应用到M语言。 Excel PowerQuery应用Excel通过M语言可以实现整体数据的清洗和重构。  PowerBI 的PowerQuery应用 PowerBI也是通过M语言来实现数据…...

【Linux】遇事不决,可先点灯,LED驱动的进化之路---1

【Linux】遇事不决&#xff0c;可先点灯&#xff0c;LED驱动的进化之路---1 前言&#xff1a; 一、最简单的LED驱动程序 1.1 字符设备驱动程序框架 1.2 程序实战 1.2.1 驱动程序&#xff08;led_drive_simple.c&#xff09; 1.2.2 应用程序&#xff08;led_test_simple.c…...

hive任务reduce步骤卡在99%原因及解决

我们在写sql的时候经常发现读取数据不多&#xff0c;但是代码运行时间异常长的情况&#xff0c;这通常是发生了数据倾斜现象。数据倾斜现象本质上是因为数据中的key分布不均匀&#xff0c;大量的数据集中到了一台或者几台机器上计算&#xff0c;这些数据的计算速度远远低于平均…...

C++11 -- lambda表达式

文章目录 lamaba表达式的引入lambda表达式语法lamabda达式各部分说明捕获列表说明 lamaba表达式底层原理探索 lamaba表达式的引入 在C11之前,如果我们想对自定义类型Goods排序,可以根据姓名,价格,学号按照从大到小或者从小到大的方式排序,可是,这样我们要写额外写6个相关的仿函…...

【开源项目】银行查询服务的设计和实现

银行查询服务的设计和实现 项目地址github&#xff1a;https://github.com/xl-echo/bankInquiryService项目地址gitee&#xff1a;https://gitee.com/xl-echo/bank-inquiry-service 银行查询服务的设计初衷是&#xff1a;为提供更加便利的查询服务&#xff0c;我们在分布式系…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...