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();
}
}

  

最新文章

  1. [Storm] Storm与asm的恩恩怨怨
  2. plist文件里的"Bundle versions string, short" 跟 "Bundle version" 的区别及作用
  3. 数论 - 组合数学 + 素数分解 --- hdu 2284 : Solve the puzzle, Save the world!
  4. 本地存储 localStorage/sessionStorage/cookie
  5. Vi Usage
  6. English Learning
  7. C# 获取汉字的拼音首字母
  8. Local IIS 7.0 - CS0016: Could not write to output file / Microsoft.Net > Framework > v4.0.30319 > Temporary ASP.NET Files
  9. Android Studio下打jar包
  10. 【转】MUD教程--巫师入门教程1
  11. 使用DTM ( Dynamic Topic Models )进行主题演化实验
  12. 开发板S3C2440挂起NFS步骤
  13. Linux防火墙配置—访问外网WEB
  14. Java线程池不错的总结博客
  15. php 微信自定义分享接口
  16. C#设计模式(5)——建造者模式
  17. matplotlib绘图不显示问题解决plt.show()
  18. react实现tab切换效果
  19. BZOJ.4939.[Ynoi2016]掉进兔子洞(莫队 bitset 分组询问)
  20. Codeforces Round #283 (Div. 2) B. Secret Combination 暴力水题

热门文章

  1. 鸟哥私房菜基础篇:认识与学习BASH习题
  2. 9-26模拟赛 By cellur925
  3. CSS3向上移动的效果
  4. AtCoder Regular Contest 081 F - Flip and Rectangles
  5. Hdu 3966 Aragorn's Story (树链剖分 + 线段树区间更新)
  6. _bzoj1191 [HNOI2006]超级英雄Hero【构图 并查集】
  7. springMVC的架构与执行流程
  8. D. Taxes 哥德巴赫猜想
  9. 用PDFMiner从PDF中提取文本文字
  10. 【前端】模拟微信上传图片(带预览,支持预览gif)