首页 > 编程语言 >FastThreadLocal源码解析

FastThreadLocal源码解析

时间:2023-04-03 15:02:39浏览次数:37  
标签:index FastThreadLocal InternalThreadLocalMap FastThreadLocalThread 源码 线程 fastGet


Netty为什么要用自己的FastThreadLocal?

threadLocal Hash冲突,检索时间长。Netty自己定义的fastThreadLocal用的是数组,直接数组下标检索快。下面以ftl作为FastThreadLocal的简称

例子

ftl只有在FastThreadLocalThread线程中运行才生效,不然会走SlowGet模式(jdk threadLocal方式)

public class Demo {
    public static void main(String[] args) throws Exception {
        FastThreadLocalThread fastThreadLocalThread = new FastThreadLocalThread(() -> {
                    FastThreadLocal<Integer> ftl = new FastThreadLocal<>();
                    ftl.set(1);
                    System.out.println(ftl.get());
                }
        );
        fastThreadLocalThread.start();
        fastThreadLocalThread.join();
        System.out.println("print main thread");
    }
}

原理解析

ftl涉及主要属性

// 1. 用于slowGet()的threadLocal
static final ThreadLocal<InternalThreadLocalMap> slowThreadLocalMap = new ThreadLocal<InternalThreadLocalMap>();
// 2. 用于fastGet()。nextIndex: 用于记录当前下标;indexedVariables: fastGet()模式下用 数组Object[] 替代hash
static final AtomicInteger nextIndex = new AtomicInteger();
Object[] indexedVariables;

ftl set设置值实现步骤:

  1. 判断是否InternalThreadLocalMap.UNSET,是则remove(ftl.set(InternalThreadLocalMap.UNSET)这样复制进入这步骤)
    1.1 将indexedVariables[index] = UNSET,调用onRemoval()移除堆、对外内存
  2. 否则InternalThreadLocalMap.get()获取
    2.1 判断 thread instanceof FastThreadLocalThread 是否成立? 成立则fastGet()
  • 不存在会初始化一个Object[] indexedVariables(默认值均为UNSET),
    并根据index设置值,如果index大于indexedVariables.length则扩容(线程index是private final int index;线程私有)
  • 扩容:Arrays.copyOf拷贝,Arrays.fill填充
    2.2 否则slowGet()。降级为JDK threadLocal,这个就不分析了
class Xxxx {
    public final void set(V value) {
        if (value != InternalThreadLocalMap.UNSET) {
            InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.get();
            setKnownNotUnset(threadLocalMap, value);
        } else {
            remove();
        }
    }
    private void setKnownNotUnset(InternalThreadLocalMap threadLocalMap, V value) {
        if (threadLocalMap.setIndexedVariable(index, value)) {// 数组形式设置
            addToVariablesToRemove(threadLocalMap, this);
        }
    }
    public static InternalThreadLocalMap get() {
        Thread thread = Thread.currentThread();
        if (thread instanceof FastThreadLocalThread) {// ftl快的模式
            return fastGet((FastThreadLocalThread) thread);
        } else {// ftl慢的模式
            return slowGet();
        }
    }
}

ftl get获取值实现步骤(简单很多):

同样会判断是否fastGet()还是slowGet(),slowGet走threadLocal不讨论,一下只讨论fastGet()以及相关后续流程

  1. fastGet()中会从indexedVariables数组中根据index获取数据,第一次会进行初始化

ftl资源回收机制

netty中对于ftl提供三种机制

  1. 用ftlt执行被FastThreadLocalRunnable wrap的Runnable任务,执行完会自动清理
  2. 显示调用remove()清理
  3. 每一个ftl注册一个Cleaner,当线程对象不强可达的时候,该Cleaner线程会将当前线程的当前ftl进行回收(netty-4.1.34已注释代码,不考虑)


标签:index,FastThreadLocal,InternalThreadLocalMap,FastThreadLocalThread,源码,线程,fastGet
From: https://blog.51cto.com/u_13854513/6166438

相关文章

  • RocketMQ NameServer启动流程解析
    具体分析可参考Gitee项目NameServer解析部分=》代码地址什么是NameServer简易Topic路由注册中心,用于支持Broker的服务注册与发现。类似Dubbo的zookeeper主要能力Broker集群管理:管理Broker集群注册信息,心跳检测broker存活路由信息管理:保存Broker集群路由信息,然后producer、consumer......
  • 1 cbv分析、2 模板、3 请求与响应 、4 session及源码分析、5 闪现、 6 请求扩展
    目录1cbv分析1.1源码分析2模板2.1py2.2html3请求与响应4session及源码分析4.1session的使用4.2源码分析4.3session执行原理5闪现6请求扩展1cbv分析#基于类的视图,写法fromflaskimportFlask,requestfromflask.viewsimportView,MethodViewapp=Flask(__......
  • ORB_SLAM3源码阅读笔记(三)
    LocalMapping线程    与Tracking线程一样,同样从LocalMapping线程的创建开始逐步对LocalMapping进行分析。1LocalMapping线程的创建mpLocalMapper=newLocalMapping(this,mpAtlas,mSensor==MONOCULAR||mSensor==IMU_MONOCULAR,mSensor==IMU_MONOCULAR||mSensor==......
  • cbv分析、模板、请求与响应、session及源码分析、闪现、请求扩展
    目录1cbv分析1.1源码分析2模板2.1py2.2html3请求与响应4session及源码分析4.1session的使用4.2源码分析4.3session执行原理5闪现6请求扩展1cbv分析#基于类的视图,写法fromflaskimportFlask,requestfromflask.viewsimportView,MethodViewapp=Flask(__......
  • 实现一个函数用来解析 URL 的 querystring
    实现如下效果consturl="https://xxxx.com?a=3&b=4&c=5&name=1+1=2";//解析后得到qs如下constqs={a:3,b:4,c:5,name:'1+1=2'};纯碎使用 javascript 完成解析函数,而不利用浏览器DOM特性API,代码如下所示,细节在注释中体现functionparse(url......
  • 成品直播源码推荐,Android 禁止下拉菜单栏
    成品直播源码推荐,Android禁止下拉菜单栏1.屏蔽非锁屏下的下拉菜单栏这种Android系统其实是提供了方法的,只不过是隐藏的,只给系统应用,也就是用mk编译的apk使用。如果第三方应用想要使用,或者Androidstuido编译方式的想要使用。则可以使用反射。 /** *Allowsanapptoco......
  • 详细解析Java异步线程处理队列任务工具类以及实战
    场景待入快速理解小场景描述:【一群人】来到【一个大厅】办理业务,大厅中有【多个窗口】给我们办理业务。每个人都有自己要办事情,处理过程需要消耗时间。大厅根据人群多少,开始窗口梳理。如果把“一群人”理解成一群待处理的n个【任务】,把这群人排成一个长队就形成了一个【任......
  • Spring源码复习
    Bean的生命周期 ApplicationContextCentralinterfacetoprovideconfigurationforanapplication.*Thisisread-onlywhiletheapplicationisrunning,butmaybe*reloadediftheimplementationsupportsthis.**<p>AnApplicationContextprovides:*<ul......
  • Mybatis配置文件解析(转载)
    流程图demo案例还是从案例开始。publicstaticvoidmain(String[]args){Stringresource="mybatis-config.xml";InputStreaminputStream=null;SqlSessionsqlSession=null;try{inputStream=Resources.getResourceAsStream(resourc......
  • 软考高项第4版教程-差异点解析来啦(第5章下)!
    第5章信息系统工程,我拆分成2篇来解析第4版教程的差异重点,上篇解析了“软件工程”和“数据工程”知识块,这次带来下篇:“系统集成”和“安全工程”知识块。“信息系统工程”文字版“系统集成”讲了4部分知识点,分别是网络集成、数据集成、软件集成和应用集成。1.系统集成4个基本原则在......