选择HttpHandler还是HttpModule?
教逝馁崭在前文中我们讲过ThreadLocal相当于是每个线程有一个小书包线程之间的小书包是隔离的只存放了属于当前线程自己的变量因此不会发生数据安全的问题。前文博客浅谈ThreadLocal----每个线程一个小书包 https://www.cnblogs.com/jilodream/p/19118986但是有时任务太繁重时父线程希望new出新的子线程来为自己的业务提供帮助同时希望子线程在处理时也能用到自己保存在ThreadLocal中的变量。现在有三种办法1直接把父线程的ThreadLocalMap传递给子线程让子线程直接拿去用如sonThread.threadLocalsparent.threadLocals2父线程在创建子线程时将子线程需要用到的ThreadLocal数据专门指定。如复制代码Thread sonThreadnew Thread(new Runnable() {Overridepublic void run() {threadLocal1.set(xxx1); //手动指定threadLocal2.set(xxx2); //手动指定threadLocal3.set(xxx3); //手动指定}});复制代码3将父线程中threadLocals 中的数据打包整理后统一传递给子线程。第一种显然不行如果两者指向了相同的Map 会导致缓存数据被共享父子线程存在并发读写又会导致安全问题。方法二虽然灵活但是指定起来过于繁琐每个子线程都要单独设置一遍。java选用的是方法三但是实现起来稍有不同java 定义了一个InheritableThreadLocal类。通过这个类来实现线程可继承的ThreadLocal定义中的Inheritable [?nher?t?bl]adj. 可继承的会遗传的InheritableThreadLocal指可以继承/遗传的ThreadLocal。接下来看源码在Thread类中定义了以下属性ThreadLocal.ThreadLocalMap inheritableThreadLocals null;类似于thread.threadLocals这是给InheritableThreadLocal 来存储可以继承的属性的Map。InheritableThreadLocal类的源码它继承了ThreadLocal复制代码public class InheritableThreadLocal extends ThreadLocal {/*** Creates an inheritable thread local variable.*/public InheritableThreadLocal() {}/*** Computes the childs initial value for this inheritable thread-local* variable as a function of the parents value at the time the child* thread is created. This method is called from within the parent* thread before the child is started.** This method merely returns its input argument, and should be overridden* if a different behavior is desired.** param parentValue the parent threads value* return the child threads initial value*/protected T childValue(T parentValue) {return parentValue;}/*** Get the map associated with a ThreadLocal.** param t the current thread*/ThreadLocalMap getMap(Thread t) {return t.inheritableThreadLocals;}/*** Create the map associated with a ThreadLocal.** param t the current thread* param firstValue value for the initial entry of the table.*/void createMap(Thread t, T firstValue) {t.inheritableThreadLocals new ThreadLocalMap(this, firstValue);}}复制代码通过源码我们可以发现它的用法和实现与ThreadLocal基本相同但是它重写了父类ThreadLocal的几个方法1首先是getMap(),重写的目的是当需要操作map对象时(防盗连接本文首发自http://www.cnblogs.com/jilodream/ )请使用inheritableThreadLocals而不是再是父类中的t.threadLocals写法这样所有使用的map就都切换到了ThreadLocal.ThreadLocalMap inheritableThreadLocals这个属性上来了。2其次是createMap() 方法该方法的主要目的是初始化Map对象这里强调了初始化的是 t.inheritableThreadLocals 属性。为啥没直接用getMap() 方法来获取 t.inheritableThreadLocals呢这是由于 t.inheritableThreadLocals 还没有初始化返回是null你调用getMap()没有意义。3最后是 childValue() 方法它是指当发生继承动作时父类中的存储的变量转化为子类对象的转化转换。这里直接抽象成方法了方便大家重写自己的InheritableThreadLocal类时可以直接重写该方法。如我们想前边加一个标签代表是子线程专用亦或者进行翻译转换等等总之方便你自己实现转换。来看下继承动作具体是怎么操作的继承主要发生在主线程创建子线程程时我们来看下Thread的构造方法源码经过一堆跳转最后会跳转进这个方法复制代码private Thread(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc,boolean inheritThreadLocals) {//....if (inheritThreadLocals parent.inheritableThreadLocals ! null)this.inheritableThreadLocals ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);/* Stash the specified stack size in case the VM cares */this.stackSize stackSize;/* Set thread ID */this.tid nextThreadID();}复制代码方法参数中的boolean inheritThreadLocals表示是否要继承/遗传。手动创建的线程这里都会是true代表要继承/遗传。parent.inheritableThreadLocals ! null 判断父线程的inheritableThreadLocals 属性是否为null 是否初始化了如果不为null父线程有需要遗传的本地变量才发生遗传动作。条件都满足则发生遗传(防盗连接本文首发自http://www.cnblogs.com/jilodream/ )入参为父线程的遗传本地变量也就是属性inheritableThreadLocals。之后进入ThreadLocalMap的构造方法开始构造子线程的inheritableThreadLocals 属性复制代码private ThreadLocalMap(ThreadLocalMap parentMap) {Entry[] parentTable parentMap.table;int len parentTable.length;setThreshold(len);table new Entry[len];for (Entry e : parentTable) {if (e ! null) {SuppressWarnings(unchecked)ThreadLocalkey (ThreadLocal) e.get();if (key ! null) {Object value key.childValue(e.value);Entry c new Entry(key, value);int h key.threadLocalHashCode (len - 1);while (table[h] ! null)h nextIndex(h, len);table[h] c;size;}}}}复制代码方法中就是遍历父线程的Map生成子线程自己的Map.Entry 了。这里注意在获取Entry的key 时通过entry.get() 拿到父线程的Map 的key的弱引用强制转化为ThreadLocal类型即可。在获取value 值时调用的是key的childValue()方法也就是InheritableThreadLocal.childValue()中重写的方法将父线程的value值转为子线程的value时。这样子线程中:1、map初始化好了2、entry元素也通过父线程都转移到子线程中了3、获取的遗传map使用的都是遗传map了。通过getMap()重写map的get set remove 等核心逻辑都直接使用父类的逻辑。因为InheritableThreadLocal继承自ThreadLocal并且没有重写这段逻辑总体上了来说ThreadLocalInheritableThreadLocal的实现都非常的优雅不但很好的利用了对象的继承保证用户在使用时无感知的发生了继承。其次用户在自定义自己的InheritableThreadLocal class时(防盗连接本文首发自http://www.cnblogs.com/jilodream/ )也只需要完成如何转化即可。非常值得我们自己在设计类结构和关系时参考这里的细节设计。类关系整体的结构如下Itlleitu除此之外我们也可以通过源码发现InheritableThreadLocal的一个特性就是属性的遗传来自于父InheritableThreadLocal的全量属性是不能根据某个线程自定义的。并且在遗传时子线程是在被new出实例时就已经获得了此刻全部的属性如果父线程后续调整了InheritableThreadLocal的范围子线程是感知不到的。来看这样一个例子即可复制代码public static void main(String[] args) {ThreadLocal tl1 new InheritableThreadLocal();ThreadLocal tl2 new InheritableThreadLocal();ThreadLocal tl3 new InheritableThreadLocal();tl1.set(t1);tl2.set(t2);Thread sonThread new Thread(new Runnable() {Overridepublic void run() {String s1 tl1.get();String s2 tl2.get();String s3 tl3.get();System.out.println(out: s1);System.out.println(out: s2);System.out.println(out: s3);}});tl2.set(newTl2Value);sonThread.start();}

相关新闻

MVVM(Knockout.js)的新尝试:多个Page,一个ViewModel

MVVM(Knockout.js)的新尝试:多个Page,一个ViewModel

偌颈僮吹通过 start.spring.io 或其他构建基础的Spring Boot工程,根据你构建应用的需要增加一些依赖,比如最后用接口提供服务的话,可以加入web模块:org.springframework.bootspring-boot-starter-web2. 注册 UnifiedTTS&#xff0…

2026/7/7 6:09:26 阅读更多 →
,写给岁的自己

,写给岁的自己

诟淘妓偈1.1 简介 ControlNet是由斯坦福大学研究者张吕敏等人于2023年提出的一种AI图像生成控制技术,核心作用是让用户在保持生成图像 “创造力” 的同时,精准控制图像的结构、姿态、轮廓、深度等关键空间信息,解决了传统扩散模型&#xff08…

2026/7/3 9:46:20 阅读更多 →
蒙特卡洛模拟电动汽车有序充放电(matlab),适合优化调度,微电网,综合能源、储能、新能源方...

蒙特卡洛模拟电动汽车有序充放电(matlab),适合优化调度,微电网,综合能源、储能、新能源方...

蒙特卡洛模拟电动汽车有序充放电(matlab),适合优化调度,微电网,综合能源、储能、新能源方向的基础入门学习 最近在折腾电动汽车充放电调度的问题,发现蒙特卡洛模拟真是个神器。今天咱们就用Matlab整点有意思的——模拟100辆电动汽…

2026/7/5 7:50:13 阅读更多 →

最新新闻

2026新手第一套电子鼓怎么选?高性价比电子鼓横评推荐

2026新手第一套电子鼓怎么选?高性价比电子鼓横评推荐

很多新手来找我咨询买鼓,问的第一句往往是:“老师,罗兰和雅马哈哪个好?”——这个问题本身就问错了。买电子鼓和买手机不一样。手机看品牌看系统,但电子鼓的核心是手感、反馈和稳定性。品牌溢价再高,敲下去…

2026/7/7 8:12:09 阅读更多 →
匿名类·学习笔记

匿名类·学习笔记

嗨!在今天的课程中,我们将继续探讨嵌套类的主题。现在是最后一组:匿名的内在阶级。 让我们回到我们的示意图:就像上一课提到的局部类一样,匿名类是一种内在类......它们也存在若干相似之处和差异。 但首先,让我们深入探讨:为什么他们被称为“匿名”? 为了回答这个问题,…

2026/7/7 8:12:09 阅读更多 →
边缘计算盒子部署完整流程:基于算能SE5/超星未来/灵犀设备的AI视频分析实战

边缘计算盒子部署完整流程:基于算能SE5/超星未来/灵犀设备的AI视频分析实战

在智能视频分析交付的最后“一公里”,边缘计算盒子凭借低功耗、小体积以及本地化算力优势,成为了私有化交付、明火烟雾检测、安全帽识别等POC现场的首选。然而,边缘端异构芯片(如ARM64架构)的复杂性、底层硬件加速驱动…

2026/7/7 8:10:09 阅读更多 →
爬虫实战:如何优雅地抓取网页中隐藏在伪元素(__before)里的文本?

爬虫实战:如何优雅地抓取网页中隐藏在伪元素(__before)里的文本?

相信很多写过一段时间爬虫的同学大概率撞过这堵“隐形墙”:在浏览器里明明白白显示着"¥9.9"的价格,或者一段验证码文本,但当你切换到 DevTools 时,发现那个数字安安静静地挂在某个标签里。然而,当…

2026/7/7 8:06:08 阅读更多 →
5分钟掌握RoundedTB:让Windows任务栏焕然一新的魔法指南

5分钟掌握RoundedTB:让Windows任务栏焕然一新的魔法指南

5分钟掌握RoundedTB:让Windows任务栏焕然一新的魔法指南 【免费下载链接】RoundedTB Add margins, rounded corners and segments to your taskbars! 项目地址: https://gitcode.com/gh_mirrors/ro/RoundedTB 想让单调的Windows任务栏瞬间变得现代时尚吗&…

2026/7/7 8:04:08 阅读更多 →
2026 视频主要内容方案选型:怎么选才能合理控制研发项目成本

2026 视频主要内容方案选型:怎么选才能合理控制研发项目成本

先说明白核心判断 针对学生群体课堂复习、论文调研、知识自测的场景,选2026年视频主要内容处理方案控制项目成本,核心逻辑是匹配需求选功能,不为用不到的企业级服务付费:轻度需求用免费额度覆盖,高频学习需求选适配学…

2026/7/7 8:00:07 阅读更多 →

日新闻

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

图片浏览是移动应用中最高频的场景之一。从社交应用的照片流到电商平台的商品图集,从旅游应用的景点相册到摄影作品展示——用户对图片浏览的体验要求不断提高:流畅的切换动画、直观的缩略图导航、便捷的收藏操作、自动播放模式。HarmonyOS NEXT ArkUI 虽…

2026/7/7 0:05:16 阅读更多 →
24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V稳压芯片完整选型指南 PW8600 PW75XX PW2815 PW2312B LDODC/DC全方案 一、24V稳压方案概述 24V直流电源在工业自动化、门禁系统、电梯控制、汽车电子、LED驱动、监控设备等场景中应用极广,是最常见的中压直流母线电压。要将24V母线稳定降压至下游MCU、传感器…

2026/7/7 0:05:16 阅读更多 →
RAG+知识图谱混合检索与Graph RAG核心对比

RAG+知识图谱混合检索与Graph RAG核心对比

做企业RAG落地的团队,往往容易卡在一容易踩坑的选型难题: 当需求单纯靠向量RAG搞不定、单纯靠知识图谱也搞不定,必须同时依赖「文本语义理解 实体关系推理」时,到底是做「向量图谱混合检索」就够了,还是必须上「Grap…

2026/7/7 0:07:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻