You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 8.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. # spring-boot-demo-async
  2. > 此 demo 主要演示了 Spring Boot 如何使用原生提供的异步任务支持,实现异步执行任务。
  3. ## pom.xml
  4. ```xml
  5. <?xml version="1.0" encoding="UTF-8"?>
  6. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  7. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  8. <modelVersion>4.0.0</modelVersion>
  9. <artifactId>spring-boot-demo-async</artifactId>
  10. <version>1.0.0-SNAPSHOT</version>
  11. <packaging>jar</packaging>
  12. <name>spring-boot-demo-async</name>
  13. <description>Demo project for Spring Boot</description>
  14. <parent>
  15. <groupId>com.xkcoding</groupId>
  16. <artifactId>spring-boot-demo</artifactId>
  17. <version>1.0.0-SNAPSHOT</version>
  18. </parent>
  19. <properties>
  20. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  21. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  22. <java.version>1.8</java.version>
  23. </properties>
  24. <dependencies>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter</artifactId>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.springframework.boot</groupId>
  31. <artifactId>spring-boot-starter-test</artifactId>
  32. <scope>test</scope>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.projectlombok</groupId>
  36. <artifactId>lombok</artifactId>
  37. <optional>true</optional>
  38. </dependency>
  39. </dependencies>
  40. <build>
  41. <finalName>spring-boot-demo-async</finalName>
  42. <plugins>
  43. <plugin>
  44. <groupId>org.springframework.boot</groupId>
  45. <artifactId>spring-boot-maven-plugin</artifactId>
  46. </plugin>
  47. </plugins>
  48. </build>
  49. </project>
  50. ```
  51. ## application.yml
  52. ```yaml
  53. spring:
  54. task:
  55. execution:
  56. pool:
  57. # 最大线程数
  58. max-size: 16
  59. # 核心线程数
  60. core-size: 16
  61. # 存活时间
  62. keep-alive: 10s
  63. # 队列大小
  64. queue-capacity: 100
  65. # 是否允许核心线程超时
  66. allow-core-thread-timeout: true
  67. # 线程名称前缀
  68. thread-name-prefix: async-task-
  69. ```
  70. ## SpringBootDemoAsyncApplication.java
  71. ```java
  72. /**
  73. * <p>
  74. * 启动器
  75. * </p>
  76. *
  77. * @author yangkai.shen
  78. * @date Created in 2018-12-29 10:28
  79. */
  80. @EnableAsync
  81. @SpringBootApplication
  82. public class SpringBootDemoAsyncApplication {
  83. public static void main(String[] args) {
  84. SpringApplication.run(SpringBootDemoAsyncApplication.class, args);
  85. }
  86. }
  87. ```
  88. ## TaskFactory.java
  89. ```java
  90. /**
  91. * <p>
  92. * 任务工厂
  93. * </p>
  94. *
  95. * @author yangkai.shen
  96. * @date Created in 2018-12-29 10:37
  97. */
  98. @Component
  99. @Slf4j
  100. public class TaskFactory {
  101. /**
  102. * 模拟5秒的异步任务
  103. */
  104. @Async
  105. public Future<Boolean> asyncTask1() throws InterruptedException {
  106. doTask("asyncTask1", 5);
  107. return new AsyncResult<>(Boolean.TRUE);
  108. }
  109. /**
  110. * 模拟2秒的异步任务
  111. */
  112. @Async
  113. public Future<Boolean> asyncTask2() throws InterruptedException {
  114. doTask("asyncTask2", 2);
  115. return new AsyncResult<>(Boolean.TRUE);
  116. }
  117. /**
  118. * 模拟3秒的异步任务
  119. */
  120. @Async
  121. public Future<Boolean> asyncTask3() throws InterruptedException {
  122. doTask("asyncTask3", 3);
  123. return new AsyncResult<>(Boolean.TRUE);
  124. }
  125. /**
  126. * 模拟5秒的同步任务
  127. */
  128. public void task1() throws InterruptedException {
  129. doTask("task1", 5);
  130. }
  131. /**
  132. * 模拟2秒的同步任务
  133. */
  134. public void task2() throws InterruptedException {
  135. doTask("task2", 2);
  136. }
  137. /**
  138. * 模拟3秒的同步任务
  139. */
  140. public void task3() throws InterruptedException {
  141. doTask("task3", 3);
  142. }
  143. private void doTask(String taskName, Integer time) throws InterruptedException {
  144. log.info("{}开始执行,当前线程名称【{}】", taskName, Thread.currentThread().getName());
  145. TimeUnit.SECONDS.sleep(time);
  146. log.info("{}执行成功,当前线程名称【{}】", taskName, Thread.currentThread().getName());
  147. }
  148. }
  149. ```
  150. ## TaskFactoryTest.java
  151. ```java
  152. /**
  153. * <p>
  154. * 测试任务
  155. * </p>
  156. *
  157. * @author yangkai.shen
  158. * @date Created in 2018-12-29 10:49
  159. */
  160. @Slf4j
  161. public class TaskFactoryTest extends SpringBootDemoAsyncApplicationTests {
  162. @Autowired
  163. private TaskFactory task;
  164. /**
  165. * 测试异步任务
  166. */
  167. @Test
  168. public void asyncTaskTest() throws InterruptedException, ExecutionException {
  169. long start = System.currentTimeMillis();
  170. Future<Boolean> asyncTask1 = task.asyncTask1();
  171. Future<Boolean> asyncTask2 = task.asyncTask2();
  172. Future<Boolean> asyncTask3 = task.asyncTask3();
  173. // 调用 get() 阻塞主线程
  174. asyncTask1.get();
  175. asyncTask2.get();
  176. asyncTask3.get();
  177. long end = System.currentTimeMillis();
  178. log.info("异步任务全部执行结束,总耗时:{} 毫秒", (end - start));
  179. }
  180. /**
  181. * 测试同步任务
  182. */
  183. @Test
  184. public void taskTest() throws InterruptedException {
  185. long start = System.currentTimeMillis();
  186. task.task1();
  187. task.task2();
  188. task.task3();
  189. long end = System.currentTimeMillis();
  190. log.info("同步任务全部执行结束,总耗时:{} 毫秒", (end - start));
  191. }
  192. }
  193. ```
  194. ## 运行结果
  195. ### 异步任务
  196. ```bash
  197. 2018-12-29 10:57:28.511 INFO 3134 --- [ async-task-3] com.xkcoding.async.task.TaskFactory : asyncTask3开始执行,当前线程名称【async-task-3】
  198. 2018-12-29 10:57:28.511 INFO 3134 --- [ async-task-1] com.xkcoding.async.task.TaskFactory : asyncTask1开始执行,当前线程名称【async-task-1】
  199. 2018-12-29 10:57:28.511 INFO 3134 --- [ async-task-2] com.xkcoding.async.task.TaskFactory : asyncTask2开始执行,当前线程名称【async-task-2】
  200. 2018-12-29 10:57:30.514 INFO 3134 --- [ async-task-2] com.xkcoding.async.task.TaskFactory : asyncTask2执行成功,当前线程名称【async-task-2】
  201. 2018-12-29 10:57:31.516 INFO 3134 --- [ async-task-3] com.xkcoding.async.task.TaskFactory : asyncTask3执行成功,当前线程名称【async-task-3】
  202. 2018-12-29 10:57:33.517 INFO 3134 --- [ async-task-1] com.xkcoding.async.task.TaskFactory : asyncTask1执行成功,当前线程名称【async-task-1】
  203. 2018-12-29 10:57:33.517 INFO 3134 --- [ main] com.xkcoding.async.task.TaskFactoryTest : 异步任务全部执行结束,总耗时:5015 毫秒
  204. ```
  205. ### 同步任务
  206. ```bash
  207. 2018-12-29 10:55:49.830 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task1开始执行,当前线程名称【main】
  208. 2018-12-29 10:55:54.834 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task1执行成功,当前线程名称【main】
  209. 2018-12-29 10:55:54.835 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task2开始执行,当前线程名称【main】
  210. 2018-12-29 10:55:56.839 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task2执行成功,当前线程名称【main】
  211. 2018-12-29 10:55:56.839 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task3开始执行,当前线程名称【main】
  212. 2018-12-29 10:55:59.843 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task3执行成功,当前线程名称【main】
  213. 2018-12-29 10:55:59.843 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactoryTest : 同步任务全部执行结束,总耗时:10023 毫秒
  214. ```
  215. ## 参考
  216. - Spring Boot 异步任务线程池的配置 参考官方文档:https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-task-execution-scheduling