有勇气的牛排博客

SpringBoot (九) @Async实现异步调用

有勇气的牛排 686 Java 2023-02-25 21:15:19

文章目录

前言

异步线程可能会非常小号cpu资源,大项目推荐使用mq异步实现。

1 App.java

@SpringBootApplication @EnableAsync // 开启异步注解 public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }

2 Controller

/* * @Author : 有勇气的牛排(全网同名) * @FileName: CsAsync.java * desc : * */ package com.couragesteak.controller; import com.couragesteak.service.MemberServiceAsync; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j public class CsAsync { @Autowired private MemberServiceAsync memberServiceAsync; // http://127.0.0.1:8080/a_register @RequestMapping("/a_register") public String A_Register() { log.info(">>> 01"); memberServiceAsync.smsAsync(); log.info(">>> 03"); return "注册成功"; } }

3 service

/* * @Author : 有勇气的牛排(全网同名) * @FileName: MemberServiceAsync.java * desc : * */ package com.couragesteak.service; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @Component @Slf4j public class MemberServiceAsync { @Async("taskExecutor") // 指定线程池 public String smsAsync() { log.info(">>> 2"); try { log.info("正在发送中"); Thread.sleep(3000); } catch (Exception e) { } return "恭喜注册成功"; } }

4 多线程池封装

/* * @Author : 有勇气的牛排(全网同名) * @FileName: ThreadPoolConfig.java * desc : 线程池配置 * */ package com.couragesteak.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.ThreadPoolExecutor; @Configuration @EnableAsync public class ThreadPoolConfig { /** * 每秒需要多少个线程处理? * tasks/(1/taskcost) */ private int corePoolSize = 3; /** * 线程池维护线程的最大数量 * (max(tasks)- queueCapacity)/(1/taskcost) */ private int maxPoolSize = 3; /** * 缓存队列 * (coreSizePool/taskcost)*responsetime */ private int queueCapacity = 10; /** * 允许的空闲时间 * 默认为60 */ private int keepAlive = 100; @Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 设置核心线程数 executor.setCorePoolSize(corePoolSize); // 设置最大线程数 executor.setMaxPoolSize(maxPoolSize); // 设置队列容量 executor.setQueueCapacity(queueCapacity); // 设置允许的空闲时间(秒) //executor.setKeepAliveSeconds(keepAlive); // 设置默认线程名称 executor.setThreadNamePrefix("thread-"); // 设置拒绝策略rejection-policy:当pool已经达到max size的时候,如何处理新任务 // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 等待所有任务结束后再关闭线程池 executor.setWaitForTasksToCompleteOnShutdown(true); return executor; } }

留言

专栏
文章
加入群聊