SpringBoot的线程调度
Spring Boot默认提供了一个ThreadPoolTaskExecutor作为线程调度器,只需要在配置类中使用注解EnableAsync即可开启异步线程调度。在实际要执行的Bean中使用@Async注解来声明这个方法是异步方法,需要通过线程调度器来执行。
示例代码如下:
Application类,开启异步线程调度
@SpringBootApplication
@EnableAsync
public class TestApplication { public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
异步任务类,声明execute()方法通过线程调度器执行
@Service
public class TestAsync { private static AtomicInteger count = new AtomicInteger(0); @Async
public String execute() {
System.out.println("begin execute TestAsync: " + count.incrementAndGet());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("finished execute TestAsync");
return "result";
}
}
要注意的问题:
(1)这里的@Async注解必须要声明在Bean对外提供的方法上,如果这个方法不是由其它类直接调用,而是这个类的其它方法间接调用,则不生效。
(2)@Async注解声明的方法,返回类型要么声明为void,要么声明为Future。因为方法是异步调用,因此无法立即返回结果,如果声明为其它返回类型,则获取到的是null。声明为Future,则可以获取到任务的执行结果。
Controller类
@RestController
public class TestAsyncController { @Autowired
private TestAsync testAsync; @RequestMapping(value = "/async", method = RequestMethod.GET)
public String async() {
System.out.println("before execute TestAsync");
String result = testAsync.outexecute();
System.out.println("after execute TestAsync");
return result;
}
}
这里获取到的result值null,因此获取这个返回值没有什么意义。
Spring Boot线程调度有以下几个参数可以配置(2.1版本之后才有):
spring.task.execution.pool.core-size # 核心线程数,默认为8
spring.task.execution.pool.queue-capacity # 队列容量,默认为无限大
spring.task.execution.pool.max-size # 最大线程数,默认为无限大
这三个参数的关系如下:
如果当前要执行的任务数超过core-size,则任务会放到队列里面等待执行,等核心线程中有任务执行完成之后,再取出队列中的任务进行调度执行。
如果等待队列已经满了,再收到新任务时,则核心线程会自动扩容,最大扩展到max-size。
spring.task.execution.pool.allow-core-thread-timeout # 是否允许回收空闲的线程,默认为true
spring.task.execution.pool.keep-alive # 空闲的线程可以保留多少秒,默认为60。如果超过这个时间没有任务调度,则线程会被回收
spring.task.execution.thread-name-prefix # 线程名前缀,默认为thread-
自定义线程调度器
如果不想使用Spring Boot自带的线程调度器,可以通过实现AsyncConfigurer接口来定义自己的线程调度器。
示例代码如下:
@Configuration
@EnableAsync
public class AppConfig implements AsyncConfigurer { @Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(7);
executor.setMaxPoolSize(42);
executor.setQueueCapacity(11);
executor.setThreadNamePrefix("MyExecutor-");
executor.initialize();
return executor;
} @Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return MyAsyncUncaughtExceptionHandler();
}
}
最新文章
- [Storm] Storm与asm的恩恩怨怨
- plist文件里的";Bundle versions string, short"; 跟 ";Bundle version"; 的区别及作用
- 数论 - 组合数学 + 素数分解 --- hdu 2284 : Solve the puzzle, Save the world!
- 本地存储 localStorage/sessionStorage/cookie
- Vi Usage
- English Learning
- C# 获取汉字的拼音首字母
- Local IIS 7.0 - CS0016: Could not write to output file / Microsoft.Net >; Framework >; v4.0.30319 >; Temporary ASP.NET Files
- Android Studio下打jar包
- 【转】MUD教程--巫师入门教程1
- 使用DTM ( Dynamic Topic Models )进行主题演化实验
- 开发板S3C2440挂起NFS步骤
- Linux防火墙配置—访问外网WEB
- Java线程池不错的总结博客
- php 微信自定义分享接口
- C#设计模式(5)——建造者模式
- matplotlib绘图不显示问题解决plt.show()
- react实现tab切换效果
- BZOJ.4939.[Ynoi2016]掉进兔子洞(莫队 bitset 分组询问)
- Codeforces Round #283 (Div. 2) B. Secret Combination 暴力水题
热门文章
- 鸟哥私房菜基础篇:认识与学习BASH习题
- 9-26模拟赛 By cellur925
- CSS3向上移动的效果
- AtCoder Regular Contest 081 F - Flip and Rectangles
- Hdu 3966 Aragorn's Story (树链剖分 + 线段树区间更新)
- _bzoj1191 [HNOI2006]超级英雄Hero【构图 并查集】
- springMVC的架构与执行流程
- D. Taxes 哥德巴赫猜想
- 用PDFMiner从PDF中提取文本文字
- 【前端】模拟微信上传图片(带预览,支持预览gif)