关于netty的FastThreadLocal的思考
Netty版本4.1.6。
与jdk的ThreadLocal相比,netty的FastThreadLoacl具有更高的读写性能,如何针对原生的ThreadLocal进行优化。
准备采用netty的FastThreadLoacl的线程都需要继承自netty实现的FastThreadLocalThread,在FastThreadLocalThread中,直接给出了如下字段。
private InternalThreadLocalMap threadLocalMap;
在这个前提下,当需要用到线程的FastThreadLocal的时候,相关操作都是在这个InternalThreadlocalMap中。
static final AtomicInteger nextIndex = new AtomicInteger();/** Used by {@link FastThreadLocal} */
Object[] indexedVariables;
InternalThreadlocalMap主要由以上两个成员组成,其中indexedVariables作为一个Object[]数组,直接用来存放ThreadLocal对应的value,相比jdk的Entry[]数组相比,并没有存放ThreadLocal的key,那么是如何界定到ThreadLocal在数组中的具体位置呢。每个FastThreadLocal对象都会在相应的线程的ThreadLocalMap中被分配到对应的index,由以上的nextIndex分配,这样当需要根据相应的ThreadLocal取得相应的值时,就可以根据相应的下标,直接在数组上定位并得到。
从另一个角度上说,也避免了原本jdk上 hash的实现方式下,线性探测法导致的多次访问Entry数组的情况。
而大多数情况下,Object数组的第一个位置并不会存放具体的FastThreadLocal对应的值。
private static final int variablesToRemoveIndex = InternalThreadLocalMap.nextVariableIndex();
在FastThreadLocal类被加载的时候,将会得到ThreadLocalMap一个值作为variablesToRemoveIndex专门用来存放当前线程所有持有的ThreadLocal变量,当一个FastThreadLocal的值进入到Object[]中,将会把这个FastThreadLocal也放到Object[]variablesToRemoveIndex下标下的Set中,当一个线程运行在线程池中,只需要调用removeAll()方法就可以通过遍历该集合的方式完成当前残留ThreadLocal数据的清理,而不需要依次遍历到Object[]数组。
public static void removeAll() {InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.getIfSet();if (threadLocalMap == null) {return;}try {Object v = threadLocalMap.indexedVariable(variablesToRemoveIndex);if (v != null && v != InternalThreadLocalMap.UNSET) {@SuppressWarnings("unchecked")Set<FastThreadLocal<?>> variablesToRemove = (Set<FastThreadLocal<?>>) v;FastThreadLocal<?>[] variablesToRemoveArray =variablesToRemove.toArray(new FastThreadLocal[variablesToRemove.size()]);for (FastThreadLocal<?> tlv: variablesToRemoveArray) {tlv.remove(threadLocalMap);}}} finally {InternalThreadLocalMap.remove();}
}
在removeAll()方法的支持下,Netty的默认线程工厂DefaultThreadFactory在产生线程时,将会默认在线程的run()方法的finally代码块中执行removeAll()。
private static final class DefaultRunnableDecorator implements Runnable {private final Runnable r;DefaultRunnableDecorator(Runnable r) {this.r = r;}@Overridepublic void run() {try {r.run();} finally {FastThreadLocal.removeAll();}}
}
除了上述的快速清理,最关键的地方在于也避免了内存泄漏和避免了jdk为了防止内存泄漏多出来启发式操作。由于在Set中,维持着对于各个FastThreadLocal中强引用,导致不会出现jdk中ThreadLocal被回收导致key不存在而产生的内存泄漏,保证removeAll()的调用会回收掉所有的FastThreadLocal,另一方面,也避免了原生的jdk的在存取过程中耗时的启发式内存泄漏检测和线性探测过程中冲突导致的泄漏处理。
关于netty的FastThreadLocal的思考相关推荐
- Netty 的 FastThreadLocal 到底快在哪里
其实呢,追踪一下常用的 Spring 等框架,会发现正常运转的情况下,一个线程最多也就三四十个 ThreadLocal 变量,那么,Netty 为何还要大费周章搞一个 FastThreadLocal ...
- Netty技术细节源码分析-FastThreadLocal源码分析
本文是该篇的修正版 本文的github地址:点此 Netty 的 FastThreadLocal 源码解析 该文中涉及到的 Netty 源码版本为 4.1.6. Netty 的 FastThreadL ...
- 2020java面试总结
博主背景:92年生,渣本毕业,java岗,经验接近6年,base上海 本文宗旨:本文旨在将博主最近的面试经历分享给大家,并作些总结,尽量为在准备面试的同学缩小面试准备的范围,或者至少让同学们知道现在企 ...
- 这玩意比ThreadLocal叼多了,吓得我赶紧分享出来。
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! Dubbo的一次提交开始 故事得从前段时间翻阅 Dubbo ...
- 何为TransmittableThreadLocal
一.示例 线程池内的线程并没有父子关系,所以不适合InheritableThreadLocal的使用场景 public class ThreadPoolInheritableThreadLocalDe ...
- ThreadLocal知识点详解
本文说下ThreadLocal的主要知识点 文章目录 概述 详解 小结 概述 ThreadLocal的作用主要是做数据隔离,填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的,在多线程环境 ...
- 拼多多面试官没想到ThreadLocal我用得这么溜,人直接傻掉
点赞再看,养成习惯,微信搜一搜[敖丙]关注这个互联网苟且偷生的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列 ...
- Go 调用 Java 方案和性能优化分享
点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 一 背景 一个 ...
- 文章汇总(Java篇)
本篇总结内容是作者2018年截至2022年的学习总结,后续将持续更新.作者将大部分业余的时间贡献给了代码实属不易,如果文章对你有帮助记得点赞收藏支持一下作者,你们的鼓励是作者最大的动力. Java J ...
最新文章
- 告别繁琐提升效率,Docker 帮您降低从开发到部署的复杂性
- python映射类型-详解Python中映射类型(字典)操作符的概念和使用
- java 缓存 单例_单例模式应用:高速缓存和查找对象(转)
- python类加载机制_PHP面向对象自动加载机制原理与用法分析
- mac中安装activeMQ
- linux系统在硬盘上安装程序,怎么样用硬盘上的镜象文件来安装Linux系统?我都进入安装界面了,但是那个安装程序好像找不到那几个镜象文件,请指点...
- nginx 4层代理配置
- Hadoop社区正式支持腾讯云COS,全球大数据开发者将无缝使用中国云存储
- linux下c语言队列,C语言队列的实现
- 电子系统中的品质因数
- word插入公式/endnote
- POJ 1862 Stripies 贪心
- 在线考试题库型App
- SMP、NUMA、MPP模型介绍
- 手把手教你批量收藏宗介和波妞壁纸
- MayaToUE4之影视动画制作流程
- 装饰模式之半透明装饰模式
- Go语言如何自定义 linter(静态检查工具)
- BPM软件是什么?BPM软件跟BPA有关联吗?
- 状态可观性和参数可辨识性
热门文章
- JAVA设计模式 - 单例模式
- Java 面向对象:封装详解
- Spring IOC容器和获取组件对象源码分析
- String常用方法大全(深入源码层面分析)
- spyder中绘图无法显示负号_Python绘图--时序图
- 百度云搜索引擎森林战士_重磅!天翼云联手百度智能云推出“天翼云百度智能建站”...
- geoserver rest 导入shape文件错误
- 技术分享连载(二十七)
- python基础之“换行符”的应用
- 基于Windows下python3.4.1IDLE常用快捷键小结