自定义线程池,实现父线程MDC的自动拷贝

1、思路

创建线程池时,我们需要一个创建线程的工厂类,一般都是重写这个工厂类来实现的,这里我们用一个更简单的方法。

线程在执行前,可以先通过MDC.getCopyOfContextMap()获取父线程的MDC的拷贝,执行时,判断这个Map是否为空,不为空设置到自己的线程的MDC即可。重写工厂类就是把这段关键代码“植入”到线程类里,其实还有一个时机做这样的事情,也就是在Runnable在提交到线程池的时候。

2. 创建MDC装饰器

实现Runnable和Callable的装饰器类:

import org.slf4j.MDC;import java.util.Map;
import java.util.concurrent.Callable;public class MDCRunnable implements Runnable {private final Runnable runnable;private final Map<String, String> contextMap;public MDCRunnable(Runnable runnable) {this.runnable = runnable;this.contextMap = MDC.getCopyOfContextMap();}@Overridepublic void run() {if (contextMap != null) {MDC.setContextMap(contextMap);}try {runnable.run();} finally {MDC.clear();}}
}public class MDCCallable<V> implements Callable<V> {private final Callable<V> callable;private final Map<String, String> contextMap;public MDCCallable(Callable<V> callable) {this.callable = callable;this.contextMap = MDC.getCopyOfContextMap();}@Overridepublic V call() throws Exception {if (contextMap != null) {MDC.setContextMap(contextMap);}try {return callable.call();} finally {MDC.clear();}}
}

3. 配置线程池

创建自定义的线程池配置类:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;@Configuration
public class ThreadPoolConfig {@Bean(name = "customThreadPool")public Executor threadPoolTaskExecutor() {// 这里按照常规方法正常创建你的线程池ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);// 这里返回一个匿名类,只重写了execute方法     return new Executor() {@Overridepublic void execute(Runnable command) {// 这里把线程包装一下executor.execute(new MDCRunnable(command));}};}
}

总结

以上两个wapper,包括这个匿名线程池也可以显示定义出来,不难看出他们都是代理类,应用了代码模式进行增强。 这个匿名线程池类在execute前,把线程用MDCRunnable包装了一个,于是线程就有了自动拷贝MDC的能力,目前这是最简单的一种方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/20886.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据中台设计方案(原版word获取)

通过中台建设实现企业能力复用&#xff0c;包括能力整合、业务创新、业务和数据闭环、组织模式演进等。 数字能力整合 企业的数字能力一般包括数字化营销、数字化产品、数字化供应链、数字化生产、数字化运营等。企业的数字化能力的充分利用&#xff0c;从而达到可持续发展。数…

基于语音识别的智能电子病历(四)语音识别的要求 3

前一章讲的是不同医院对语言识别结果的个性化需求&#xff0c;现在说一下不同的医生对于识别结果的需求。我们看下面的这个例子&#xff0c;例子中对很多细节都有明确的要求。 004X医院4811XX医生 规范 医生基本信息&#xff1a;4811XX--dictating doctXXXX H. LXXXXX MD-CARD …

使用IDEA在WSL2的Ubuntu的docker中运行项目

1、新建项目 1.1 从远程仓库拉取代码 2、配置环境 2.1 配置IDEA运行环境 2.1.1 配置JDK 注意&#xff1a;Ubuntu 20.04运行项目请使用JDK11&#xff0c;使用JDK8会编译报错&#xff0c;报错如下&#xff1a; 2.1.2 配置Maven 2.1.3 配置运行环境 2.1.4 配置远程Debug 2.2、配…

基础—SQL—DQL(数据查询语言)分组查询

一、引言 分组查询的关键字是&#xff1a;GROUP BY。 二、DQL—分组查询 1、语法 SELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组后过滤条件 ]; 注意&#xff1a; 1、[ ] 里的内容可以有可以没有。 2、这条SQL语句有两块指定条件的地方&#…

抖音小店如何经营无货源产品!

一、开店 店铺类型要选择个体店&#xff0c;不要选择个人店或者企业店铺。 个人店的限制太多&#xff0c;没有发展的空间&#xff0c;企业店不适合新手操作&#xff0c;而且还涉及复杂的税务问题。 我们直接在抖音小店官网按照系统的要求&#xff0c;一步步提交营业执照&…

GPT-4o:人工智能新纪元的启航者

引言 随着人工智能技术的不断进步&#xff0c;我们见证了从简单的自动化工具到复杂的决策支持系统的演变。在这一演变过程中&#xff0c;OpenAI的GPT系列无疑占据了领导地位。最近&#xff0c;GPT-4o的推出再次引发了关于AI能力的广泛讨论。本文将对GPT-4o进行详细评价&#x…

代码随想录算法训练营第二十五天 | 216.组合总和III、17.电话号码的字母组合

216.组合总和III 题目链接&#xff1a;https://leetcode.cn/problems/combination-sum-iii/ 文档讲解&#xff1a;https://programmercarl.com/0216.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CIII.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV1wg411873x 思路 未剪…

Kubernetes 文档 / 概念 / 服务、负载均衡和联网 / EndpointSlice

Kubernetes 文档 / 概念 / 服务、负载均衡和联网 / EndpointSlice 此文档从 Kubernetes 官网摘录 中文地址 英文地址 Kubernetes 的 EndpointSlice API 提供了一种简单的方法来跟踪 Kubernetes 集群中的网络端点&#xff08;network endpoints&#xff09;。EndpointSlices 为…

Python:由b站临时短链接获取到永久链接(去除分享中的杂项)

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️如遇文章付费&#xff0c;可先看…

首套真题解析!安徽211难度适中!两门课!

这个系列会分享名校真题。并做详细解析&#xff01;此为24年第一套&#xff01; 今天分享的是22年合肥工业856的信号与系统试题及解析。 小马哥Tips&#xff1a; 本套试卷难度分析&#xff1a;本套试题内容难度中等&#xff0c;里面较多的考察了信号与系统的知识&#xff0c…

Java—自定义异常

如何自定义异常 在你的自定义异常类中提供一个构造函数来调用父类 Exception 的构造函数&#xff0c;并传递异常消息。这样做可以确保异常消息能够被正确地设置并且可以被捕获和处理。 下面是一个更完整的例子&#xff0c;展示了如何在自定义异常类中提供构造函数来传递异常消…

图论第三天

似乎要团建了&#xff0c;我再猫会。我必须参与上团建再走。 130.被围绕的区域 先把外围的O变成A&#xff0c;再把飞地的O变成X&#xff0c;再把外围A变回O class Solution { public:int neighbor[4][2] {1,0,0,-1,-1,0,0,1};void solve(vector<vector<char>>&a…

Nodejs-- 网络编程

网络编程 构建tcp服务 TCP tcp全名为传输控制协议。再osi模型中属于传输层协议。 tcp是面向连接的协议&#xff0c;在传输之前需要形成三次握手形成会话 只有会话形成了&#xff0c;服务端和客户端才能想发送数据&#xff0c;在创建会话的过程中&#xff0c;服务端和客户…

Mac vm虚拟机激活版:VMware Fusion Pro for Mac支持Monterey 1

相信之前使用过Win版系统的朋友们对这款VMware Fusion Pro for Mac应该都不会陌生&#xff0c;这款软件以其强大的功能和适配能力广受用户的好评&#xff0c;在Mac端也同样是一款最受用户欢迎之一的虚拟机软件&#xff0c;VM虚拟机mac版可以让您能够轻松的在Apple的macOS和Mac的…

字符串转换为整数

在Java中&#xff0c;将字符串转换为整数通常使用Integer.parseInt()方法。这是一个静态方法&#xff0c;可以直接将字符串表示的数字转换为整数。让我们详细解释这个过程&#xff0c;并提供一些示例代码。 Integer.parseInt()方法 语法 int number Integer.parseInt(Strin…

Java(八)——String类

文章目录 String类String的构造及内存分布构造内存分布 常用方法判等比较查找转化替换拆分截取 字符串的不可变性StringBuilder和StringBuffer String类 C语言中没有专门的字符串类型&#xff0c;一般使用字符数组或字符指针表示字符串&#xff0c;而字符串的函数需要包含头文…

【云原生】Kubernetes----配置资源管理Secrets与ConfigMaps

目录 一、Secrets &#xff08;一&#xff09;Secrets概述 &#xff08;二&#xff09;Secrets类型 &#xff08;三&#xff09;Secrets使用方式 &#xff08;四&#xff09;创建Secrets 1.陈述式命令创建 1.1 定义用户与密码文件 1.2 使用陈述式命令创建 2.使用base6…

详解智慧互联网医院系统源码:开发医院小程序教学

本篇文章&#xff0c;笔者将详细介绍智慧互联网医院系统的源码结构&#xff0c;并提供开发医院小程序的详细教学。 一、智慧互联网医院系统概述 智慧互联网医院系统涵盖了预约挂号、在线咨询、电子病历、药品管理等多个模块。 二、系统源码结构解析 智慧互联网医院系统的源码…

OpenShift 4 - OpenShift Service Mesh 3 预览

《OpenShift / RHEL / DevSecOps 汇总目录》 了解 OpenShift Service Mesh 3 的变化 OpenShift Service Mesh 是一套在 OpenShift 上安装部署、跟踪监控 Istio 运行环境的实现。红帽在 2023 年底推出了技术预览版的 OpenShift Service Mesh 3&#xff0c;它和目前的 OpenShif…

IP代理池是什么?

从事跨境行业的朋友们总会有一个疑问&#xff0c;为什么自己所合作的IP代理商的IP在使用的过程中账号会有莫名封禁的问题&#xff0c;会不会是自己在使用的过程中错误的操作违反了平台的规则&#xff0c;其实不然有可能会是IP代理池纯净度不高的问题&#xff0c;有可能自己在使…