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());}复制代码
推荐阅读
- springboot添加动态日志自动保存7天
- 大公司为什么禁止在SpringBoot项目中使用@Autowired注解?
- SpringBoot优雅的集成EhCache
- 跨平台Python异步聊天机器人框架,支持QQ、飞书、钉钉等渠道
- AMD|24核32线程、能上6GHz!Intel确认13代酷睿性能提升41%
- AMD|低功耗16线程的对决!i5-1240P VS 锐龙7 6850U:酷睿不插电也满血
- RabbitMQ之springboot操作
- 线程也不是越多越好,多少是好?
- Spring、SpringBoot和SpringCloud的基础入门
- springboot 缓存一致性常用解决方案
