通过CLR同步SQL Server和Sharepoint List数据(三)
菲示嚎且在前文中我们讲过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();}

相关新闻

Flutter 三方库 soundcloud_explode_dart 的鸿蒙化适配指南 - 实现高性能的 SoundCloud 媒体内容解析、支持音频流下载与全量元数据透传

Flutter 三方库 soundcloud_explode_dart 的鸿蒙化适配指南 - 实现高性能的 SoundCloud 媒体内容解析、支持音频流下载与全量元数据透传

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net Flutter 三方库 soundcloud_explode_dart 的鸿蒙化适配指南 - 实现高性能的 SoundCloud 媒体内容解析、支持音频流下载与全量元数据透传 前言 在进行 Flutter for OpenHarmony 的音视频或…

2026/7/12 15:06:09 阅读更多 →
外部切面不需要什么前置通知、后置通知、异常通知和环绕通知,只需提供一个同名方法就可以了。之所以可以这么简洁,是因为使用了洋葱圈模型。 ...

外部切面不需要什么前置通知、后置通知、异常通知和环绕通知,只需提供一个同名方法就可以了。之所以可以这么简洁,是因为使用了洋葱圈模型。 ...

涡馗收温在前面的文章《10min搭建一个大模型智能客服助手》中,我们详细介绍了搭建大模型智能客服的详细过程。 但是,这种基于工作流知识库的模式的方案只能解决通用的问答,还不够""智能""。 所以,我继续增加&…

2026/7/13 1:07:20 阅读更多 →
在PySide/PyQt的开发框架中,增加对表格多种格式录入的处理,以及主从表的数据显示和保存操作。

在PySide/PyQt的开发框架中,增加对表格多种格式录入的处理,以及主从表的数据显示和保存操作。

宰邪肪壮探秘Transformer系列之(1):注意力机制 0x00 概述 因为各种事情,好久没有写博客了,之前写得一些草稿也没有时间整理(都没有时间登录博客和微信,导致最近才发现好多未读消息和私信&#x…

2026/7/11 22:36:36 阅读更多 →

最新新闻

Jupyter Lab扩展分层装配指南:从变量监控到PDF交付

Jupyter Lab扩展分层装配指南:从变量监控到PDF交付

1. 项目概述:为什么一个Jupyter Notebook用户会反复重装插件?“Jupyter Extensions to Improve your Data Workflow”——这个标题乍看像是一篇泛泛而谈的工具推荐文,但如果你连续三个月每天打开Jupyter Lab写模型、调参数、画图、写报告&…

2026/7/14 3:20:17 阅读更多 →
描述性分析:数据建模前必须完成的底层校准与风险过滤

描述性分析:数据建模前必须完成的底层校准与风险过滤

1. 这不是“随便看看”的统计,而是决策前必须完成的底层校准“Descriptive Analysis”——光看这个词组,很多人第一反应是“哦,就是画几个柱状图、算几个平均数”,甚至觉得它不如回归模型或机器学习高大上。我带过二十多个数据分析…

2026/7/14 3:20:17 阅读更多 →
Linux自主访问控制(DAC)原理与虚拟化安全实践

Linux自主访问控制(DAC)原理与虚拟化安全实践

1. 自主访问控制机制(DAC)基础解析自主访问控制(Discretionary Access Control,DAC)是操作系统安全中最基础也最广泛应用的访问控制模型。它的核心思想是将资源访问权限的决定权交给资源所有者,这种"自…

2026/7/14 3:16:16 阅读更多 →
MATLAB实现的可运行超级玛丽小游戏,含完整源码、关卡数据、音效与操作指引

MATLAB实现的可运行超级玛丽小游戏,含完整源码、关卡数据、音效与操作指引

本文还有配套的精品资源,点击获取 简介:直接在MATLAB 2020b环境下运行的超级玛丽风格游戏,主程序main.m一键启动,无需编译或额外工具箱。内置三个预设关卡(保存在mario_stages.mat中),角色动…

2026/7/14 3:14:16 阅读更多 →
多维聚合数据操纵:从GROUP BY到OLAP立方体的工程实践

多维聚合数据操纵:从GROUP BY到OLAP立方体的工程实践

1. 这不是普通的数据分组——多维聚合里的“数据变形术”真正难在哪?你有没有遇到过这样的场景:销售报表里要同时按地区、产品线、季度、客户等级四个维度交叉统计销售额,还要叠加计算同比、环比、占比、滚动3期均值,最后导出时还…

2026/7/14 3:12:15 阅读更多 →
多维聚合中的数据操纵:维度裁剪、条件重算与流式再加工

多维聚合中的数据操纵:维度裁剪、条件重算与流式再加工

1. 项目概述:当数据聚合从“加总”走向“空间折叠”你有没有遇到过这样的场景:销售报表里,区域经理要按“省份→城市→门店”三级下钻看毛利,财务总监却需要把同一份数据按“产品线→季度→销售渠道”重新切片分析,而风…

2026/7/14 3:10:15 阅读更多 →

日新闻

AI Agent数据越界行为如何被精准溯源?——基于GDPR/CCPA双合规的5层审计框架实战指南

AI Agent数据越界行为如何被精准溯源?——基于GDPR/CCPA双合规的5层审计框架实战指南

更多请点击: https://kaifayun.com 第一章:AI Agent数据越界行为的合规性挑战与溯源必要性 AI Agent在自主执行任务过程中,可能因提示注入、上下文污染或权限配置缺陷,无意或有意访问、缓存、传输受保护数据(如PII、G…

2026/7/14 0:01:13 阅读更多 →
Perplexity vs ChatGPT vs Claude:实测127组复杂查询任务,谁才是真正可靠的“事实型AI助手”?

Perplexity vs ChatGPT vs Claude:实测127组复杂查询任务,谁才是真正可靠的“事实型AI助手”?

更多请点击: https://codechina.net 第一章:Perplexity 怎么用 Perplexity 是衡量语言模型预测能力的核心指标,数值越低表示模型对文本序列的不确定性越小、预测越精准。它本质上是交叉熵损失的指数形式,计算公式为:…

2026/7/14 0:01:13 阅读更多 →
全球首发!五一视界定制物理AI卫星ECS-1剑指万亿赛道

全球首发!五一视界定制物理AI卫星ECS-1剑指万亿赛道

五一视界发布公告,近日,公司与环天智慧科技股份有限公司(“环天智慧”)正式达成空天领域战略合作。环天智慧是国内领先、聚焦天基对地观测遥感卫星总体研制与在轨运营的商业航天企业,同时也是西南地区规模最大、具备全自主可控遥感卫星星座建…

2026/7/14 0:03:13 阅读更多 →

周新闻

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨 在一个阳光明媚的上午,互联网大厂的面试官坐在桌前,准备迎接他的面试候选人——燕双非,一个以搞笑和幽默著称的程序员。第一轮提问 面试官:燕双非,作…

2026/7/13 4:38:36 阅读更多 →
车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估在智能驾驶和车联网技术快速发展的今天,车载以太网作为新一代车载网络的核心传输技术,其物理层性能直接决定了数据传输的可靠性和稳定性。1000BASE-T1作为当前主流的…

2026/7/13 4:38:38 阅读更多 →
VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战指南嵌入式开发领域正经历一场工具链的静默革命。当传统Keil用户首次打开VSCode的扩展市场搜索EIDE时,往往会惊讶于这个看似简单的插件竟能重构十余年的开发习惯。本文将揭示如何用五个精准步骤&#xff0…

2026/7/13 4:38:40 阅读更多 →

月新闻