SpringBoot异步线程,父子线程数据传递的5种姿势( 二 )

AsyncServiceImpl/*** 使用RequestAttributes获取主线程传递的数据* @return* @throws InterruptedException*/@Async("asyncServiceExecutor")public CompletableFuture<String> executeValueAsync3() throws InterruptedException {log.info("start executeValueAsync");System.out.println("异步线程执行返回结果......+");RequestAttributes attributes = RequestContextHolder.getRequestAttributes();Object userId = attributes.getAttribute("userId", 0);log.info("end executeValueAsync");return CompletableFuture.completedFuture(userId.toString());}复制代码Test2Controller/*** RequestContextHolder+TaskDecorator的方式* @return* @throws InterruptedException* @throws ExecutionException*/@GetMapping("/test3")public String test3() throws InterruptedException, ExecutionException {RequestAttributes attributes = RequestContextHolder.getRequestAttributes();attributes.setAttribute("userId","123456",0);CompletableFuture<String> completableFuture = asyncService.executeValueAsync3();String s = completableFuture.get();return s;}复制代码姿势3:MDC+TaskDecorator自定义MDCTaskDecorator
/** * 线程池修饰类 */public class MDCTaskDecorator implements TaskDecorator {@Overridepublic Runnable decorate(Runnable runnable) {// 获取主线程中的请求信息(我们的用户信息也放在里面)String userId = MDC.get("userId");Map<String, String> copyOfContextMap = MDC.getCopyOfContextMap();System.out.println(copyOfContextMap);return () -> {try {// 将主线程的请求信息,设置到子线程中MDC.put("userId",userId);// 执行子线程,这一步不要忘了runnable.run();} finally {// 线程结束,清空这些信息,否则可能造成内存泄漏MDC.clear();}};}}复制代码ExecutorConfig在原来的基础上增加 executor.setTaskDecorator(new MDCTaskDecorator());
@Bean(name = "asyncServiceExecutor")public Executor asyncServiceExecutor() {log.info("start asyncServiceExecutor----------------");//ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();//使用可视化运行状态的线程池ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();//配置核心线程数executor.setCorePoolSize(corePoolSize);//配置最大线程数executor.setMaxPoolSize(maxPoolSize);//配置队列大小executor.setQueueCapacity(queueCapacity);//配置线程池中的线程的名称前缀executor.setThreadNamePrefix(namePrefix);// rejection-policy:当pool已经达到max size的时候,如何处理新任务// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());//增加MDC的线程池修饰类executor.setTaskDecorator(new MDCTaskDecorator());//执行初始化executor.initialize();log.info("end asyncServiceExecutor------------");return executor;}复制代码AsyncServiceImpl/*** 使用MDC获取主线程传递的数据* @return* @throws InterruptedException*/@Async("asyncServiceExecutor")public CompletableFuture<String> executeValueAsync5() throws InterruptedException {log.info("start executeValueAsync");System.out.println("异步线程执行返回结果......+");log.info("end executeValueAsync");return CompletableFuture.completedFuture(MDC.get("userId"));}复制代码Test2Controller/*** 使用MDC+TaskDecorator方式* 本质也是ThreadLocal+TaskDecorator方式* @return* @throws InterruptedException* @throws ExecutionException*/@GetMapping("/test5")public String test5() throws InterruptedException, ExecutionException {MDC.put("userId","123456");CompletableFuture<String> completableFuture = asyncService.executeValueAsync5();String s = completableFuture.get();return s;}复制代码姿势4:InheritableThreadLocal用户工具类 UserInheritableUtils
//** *使用InheritableThreadLocal存储线程之间共享的数据变量,如登录的用户信息 */public class UserInheritableUtils {private staticfinalInheritableThreadLocal<String> userLocal=new InheritableThreadLocal<>();public staticString getUserId(){return userLocal.get();}public static void setUserId(String userId){userLocal.set(userId);}public static void clear(){userLocal.remove();}}复制代码AsyncServiceImpl/*** 使用InheritableThreadLocal获取主线程传递的数据* @return* @throws InterruptedException*/@Async("asyncServiceExecutor")public CompletableFuture<String> executeValueAsync4() throws InterruptedException {log.info("start executeValueAsync");System.out.println("异步线程执行返回结果......+");log.info("end executeValueAsync");return CompletableFuture.completedFuture(UserInheritableUtils.getUserId());}复制代码


推荐阅读