首页 > 其他分享 > TaskDecorator——异步多线程中传递上下文等变量

TaskDecorator——异步多线程中传递上下文等变量

时间:2023-08-11 10:23:27浏览次数:38  
标签:异步 多线程 TaskDecorator 传递 线程 executor 上下文

目录

TaskDecorator

定义TaskDecorator实例

线程池使用TaskDecorator


开发中很多数据如oauth2的认证信息,日志TracerId都是在请求线程中的,如果内部使用多线程处理就存在获取不到认证信息或TraceId的问题。这时候就需要处理子线程与主线程间数据传递的问题。

TaskDecorator

这个问题需要使用线程的ThreadLocal和TaskDecorator来处理。官方文档中描述意思是TaskDecorator是一个执行回调方法的装饰器,主要应用于传递上下文,或者提供任务的监控/统计信息。

实现方式就是定义一个TaskDecorator,在线程池中设置使用这个TaskDecorator。

注意线程池中有的线程是一直存在一直被复用的,所以线程执行完成后需要在TaskDecorator的finally方法中移除传递的上下文对象,否则就存在内存泄漏的问题。

定义TaskDecorator实例

继承TaskDecorator接口创建ContextCopyingDecorator 实现类,重写decorate方法,设置需要传递的上下文和变量值。注意finally代码块。

  1.   public class ContextCopyingDecorator implements TaskDecorator {
  2.   @Override
  3.   public Runnable decorate(Runnable runnable) {
  4.   try {
  5.   RequestAttributes context = RequestContextHolder.currentRequestAttributes(); //1
  6.   Map<String,String> previous = MDC.getCopyOfContextMap(); //2
  7.   SecurityContext securityContext = SecurityContextHolder.getContext(); //3
  8.   return () -> {
  9.   try {
  10.   RequestContextHolder.setRequestAttributes(context); //1
  11.   MDC.setContextMap(previous); //2
  12.   SecurityContextHolder.setContext(securityContext); //3
  13.   runnable.run();
  14.   } finally {
  15.   RequestContextHolder.resetRequestAttributes(); // 1
  16.   MDC.clear(); // 2
  17.   SecurityContextHolder.clearContext(); // 3
  18.   }
  19.   };
  20.   } catch (IllegalStateException e) {
  21.   return runnable;
  22.   }
  23.   }
  24.   }

线程池使用TaskDecorator

  1.   @Bean
  2.   public TaskExecutor taskExecutor() {
  3.   ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  4.   executor.setCorePoolSize(corePoolSize);
  5.   executor.setMaxPoolSize(maxPoolSize);
  6.   executor.setQueueCapacity(queueCapacity);
  7.   executor.setThreadNamePrefix("MyExecutor-");
  8.    
  9.   // for passing in request scope context
  10.   executor.setTaskDecorator(new ContextCopyingDecorator());
  11.    
  12.   executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  13.   executor.setWaitForTasksToCompleteOnShutdown(true);
  14.   executor.initialize();
  15.   return executor;
  16.   }

 

标签:异步,多线程,TaskDecorator,传递,线程,executor,上下文
From: https://www.cnblogs.com/tiancai/p/17622342.html

相关文章

  • .NET Core多线程 (4) 锁机制
    合集:.NETCore多线程温故知新.NETCore多线程(1)Thread与Task.NETCore多线程(2)异步-上.NETCore多线程(3)异步-下.NETCore多线程(4)锁机制.NETCore多线程(5)常见性能问题 去年换工作时系统复习了一下.NETCore多线程相关专题,学习了一线码农老哥的《.NET5多线程编程实战》......
  • CompletableFuture异步多线程
    importjava.util.concurrent.CompletableFuture;importjava.util.concurrent.ExecutionException;publicstaticvoidmain(String[]args)throwsInterruptedException,ExecutionException{longstartTime=System.currentTimeMillis();//调用用户服......
  • java多线程:死锁
    一、死锁的定义   多线程以及多进程改善了系统资源的利用率并提高了系统的处理能力。然而,并发执行也带来了新的问题——死锁。所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。   所谓死锁是指两个或两个以上的线程在......
  • 多线程(三)
    1、线程安全的懒汉式1.1、线程安全的懒汉式,代码如下://一个单一设计模式的类如下:publicclassBank{privatedoubleaccount;privateStringname;privatestaticBankinstance=null;//私有化构造器privateBank(){}privateBank(dou......
  • python多线程学习记录
    Python多线程参考文章:python多线程详解(超详细)、Python线程池(threadpool)创建及使用+实例代码、第二十章多线程1、多线程的概念2、python多线程的基本使用方法3、多线程的优点及与多进程的关系1、多线程的概念线程也叫轻量级进程,是操作系统能够进行运算调度......
  • 异步编程和多线程的关系
    引用自“https://zhuanlan.zhihu.com/p/570792890中bluecyan的留言”异步编程,它允许我们多个任务(Task)可以同时执行。多线程技术就是CPU利用多个线程来并发地运行多段逻辑。任务是逻辑层面的,线程是操作系统层面的,由线程ID标识,任务比线程抽象层级更高。异步任务可由线程实现,也可......
  • java定时任务中创建多线程却只有一个线程运行的问题
    在定时任务中开启了多线程。。但是却只有第一个线程运行。。原因是?参考:https://www.cnpython.com/java/515558在您的例子中,它是MyRunnable的单个实例,因此当一个线程在synchronized块内执行工作时,所有其他线程将等待工作完成。因此,有效地说,一次只有一个线程在做真正的工作......
  • .NET Core多线程 (2) 异步 - 上
    去年换工作时系统复习了一下.NETCore多线程相关专题,学习了一线码农老哥的《.NET5多线程编程实战》课程,我将复习的知识进行了总结形成本专题。本篇,我们来复习一下异步的相关知识点,预计阅读时间10分钟。理解异步的本质(1)异步是什么?举个例子,在高峰期去餐厅吃饭,会先排队拿个小票,......
  • 最新版 redis-py 操作 redis(同步、异步、集群、连接池)
    现在的Python异步操作redis,有三种(aredis、aioredis、asynio_redis)但是都不推荐背景从redis.py4.2.0rc1+开始,Aioredis已经集成到redis-py中,并且Aioredis将不再更新维护,导入方式:fromredisimportasyncioasaioredis,本次验证的是redis==4.6.0#!/usr/bin/e......
  • 在使用异步请求后把值存入localstore并且在其他变量中首次通过localstore获取不到值
    问题写了一个方法A,里面有使用AXIOS进行请求(异步),并且把请求后的数据存入localstore,此方法在onMounted中进行调用,之后在其他地方使用时(通过读取localstore来获取值并给变量赋值),发现首次调用是获取不了值进行展示的,刷新后或者切换页面回来后就是按预期展示了。推断方法A是异步执行......