知乎专栏 |
启用异步执行 @EnableAsync
@EnableAsync @SpringBootApplication public class ThreadPoolApplication { public static void main(String[] args) { SpringApplication.run(ThreadPoolApplication.class, args); } }
编写异步执行代码
@Component @Slf4j public class AsyncTask { @Async public void asyncRun() throws InterruptedException { Thread.sleep(10); log.info(Thread.currentThread().getName()+":处理完成"); } }
默认线程池的配置很简单,配置参数如下:
spring.task.execution.pool.core-size:线程池创建时的初始化线程数,默认为8 spring.task.execution.pool.max-size:线程池的最大线程数,默认为int最大值 spring.task.execution.pool.queue-capacity:用来缓冲执行任务的队列,默认为int最大值 spring.task.execution.pool.keep-alive:线程终止前允许保持空闲的时间 spring.task.execution.pool.allow-core-thread-timeout:是否允许核心线程超时 spring.task.execution.shutdown.await-termination:是否等待剩余任务完成后才关闭应用 spring.task.execution.shutdown.await-termination-period:等待剩余任务完成的最大时间 spring.task.execution.thread-name-prefix:线程名的前缀,设置好了之后可以方便我们在日志中查看处理任务所在的线程池
具体配置含义如下:
spring.task.execution.pool.core-size=8 spring.task.execution.pool.max-size=20 spring.task.execution.pool.queue-capacity=10 spring.task.execution.pool.keep-alive=60s spring.task.execution.pool.allow-core-thread-timeout=true spring.task.execution.shutdown.await-termination=true spring.task.execution.shutdown.await-termination-period=60 spring.task.execution.thread-name-prefix=simple-
spring: task: execution: thread-name-prefix: task- # 线程池的线程名的前缀。默认为 task- ,建议根据自己应用来设置 pool: # 线程池相关 core-size: 8 # 核心线程数,线程池创建时候初始化的线程数。默认为 8 。 max-size: 20 # 最大线程数,线程池最大的线程数,只有在缓冲队列满了之后,才会申请超过核心线程数的线程。默认为 Integer.MAX_VALUE keep-alive: 60s # 允许线程的空闲时间,当超过了核心线程之外的线程,在空闲时间到达之后会被销毁。默认为 60 秒 queue-capacity: 200 # 缓冲队列大小,用来缓冲执行任务的队列的大小。默认为 Integer.MAX_VALUE 。 allow-core-thread-timeout: true # 是否允许核心线程超时,即开启线程池的动态增长和缩小。默认为 true 。 shutdown: await-termination: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true await-termination-period: 60 # 等待任务完成的最大时长,单位为秒。默认为 0 ,根据自己应用来设置
直接使用 @Async 注解,即可调用默认线程池
@Component public class Task { @Async public void doTaskOne() throws Exception { // 业务逻辑 } @Async public void doTaskTwo() throws Exception { // 业务逻辑 } @Async public void doTaskThree() throws Exception { // 业务逻辑 } }
this 调用方法 @Async 将失效,编程同步阻塞执行。例如下面的 doTaskThree() 会同步执行 this.doTaskOne(); 和 this.doTaskTwo();
@Component public class Task { @Async public void doTaskOne() throws Exception { // 业务逻辑 } @Async public void doTaskTwo() throws Exception { // 业务逻辑 } public void doTaskThree() throws Exception { this.doTaskOne(); this.doTaskTwo(); } }
SimpleAsyncTaskExecutor Bean 名字是 applicationTaskExecutor
"applicationTaskExecutor": { "aliases": [ "taskExecutor" ], "scope": "singleton", "type": "org.springframework.core.task.SimpleAsyncTaskExecutor", "resource": "class path resource [org/springframework/boot/autoconfigure/task/TaskExecutorConfigurations$TaskExecutorConfiguration.class]", "dependencies": [ "org.springframework.boot.autoconfigure.task.TaskExecutorConfigurations$TaskExecutorConfiguration", "simpleAsyncTaskExecutorBuilder" ] }
package cn.netkiller.service; import lombok.extern.slf4j.Slf4j; import org.springframework.cache.annotation.Cacheable; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @Service @Slf4j public class TestService { @Async("applicationTaskExecutor") public void thread() { log.info("applicationTaskExecutor"); } }
2024-02-02T18:20:50.938+08:00 INFO 91307 --- [watch-development] [ simple-2] cn.netkiller.service.TestService : applicationTaskExecutor