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.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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. * @package: com.xkcoding.async
  78. * @description: 启动器
  79. * @author: yangkai.shen
  80. * @date: Created in 2018-12-29 10:28
  81. * @copyright: Copyright (c) 2018
  82. * @version: V1.0
  83. * @modified: yangkai.shen
  84. */
  85. @EnableAsync
  86. @SpringBootApplication
  87. public class SpringBootDemoAsyncApplication {
  88. public static void main(String[] args) {
  89. SpringApplication.run(SpringBootDemoAsyncApplication.class, args);
  90. }
  91. }
  92. ```
  93. ## TaskFactory.java
  94. ```java
  95. /**
  96. * <p>
  97. * 任务工厂
  98. * </p>
  99. *
  100. * @package: com.xkcoding.async.task
  101. * @description: 任务工厂
  102. * @author: yangkai.shen
  103. * @date: Created in 2018-12-29 10:37
  104. * @copyright: Copyright (c) 2018
  105. * @version: V1.0
  106. * @modified: yangkai.shen
  107. */
  108. @Component
  109. @Slf4j
  110. public class TaskFactory {
  111. /**
  112. * 模拟5秒的异步任务
  113. */
  114. @Async
  115. public Future<Boolean> asyncTask1() throws InterruptedException {
  116. doTask("asyncTask1", 5);
  117. return new AsyncResult<>(Boolean.TRUE);
  118. }
  119. /**
  120. * 模拟2秒的异步任务
  121. */
  122. @Async
  123. public Future<Boolean> asyncTask2() throws InterruptedException {
  124. doTask("asyncTask2", 2);
  125. return new AsyncResult<>(Boolean.TRUE);
  126. }
  127. /**
  128. * 模拟3秒的异步任务
  129. */
  130. @Async
  131. public Future<Boolean> asyncTask3() throws InterruptedException {
  132. doTask("asyncTask3", 3);
  133. return new AsyncResult<>(Boolean.TRUE);
  134. }
  135. /**
  136. * 模拟5秒的同步任务
  137. */
  138. public void task1() throws InterruptedException {
  139. doTask("task1", 5);
  140. }
  141. /**
  142. * 模拟2秒的同步任务
  143. */
  144. public void task2() throws InterruptedException {
  145. doTask("task2", 2);
  146. }
  147. /**
  148. * 模拟3秒的同步任务
  149. */
  150. public void task3() throws InterruptedException {
  151. doTask("task3", 3);
  152. }
  153. private void doTask(String taskName, Integer time) throws InterruptedException {
  154. log.info("{}开始执行,当前线程名称【{}】", taskName, Thread.currentThread().getName());
  155. TimeUnit.SECONDS.sleep(time);
  156. log.info("{}执行成功,当前线程名称【{}】", taskName, Thread.currentThread().getName());
  157. }
  158. }
  159. ```
  160. ## TaskFactoryTest.java
  161. ```java
  162. /**
  163. * <p>
  164. * 测试任务
  165. * </p>
  166. *
  167. * @package: com.xkcoding.async.task
  168. * @description: 测试任务
  169. * @author: yangkai.shen
  170. * @date: Created in 2018-12-29 10:49
  171. * @copyright: Copyright (c) 2018
  172. * @version: V1.0
  173. * @modified: yangkai.shen
  174. */
  175. @Slf4j
  176. public class TaskFactoryTest extends SpringBootDemoAsyncApplicationTests {
  177. @Autowired
  178. private TaskFactory task;
  179. /**
  180. * 测试异步任务
  181. */
  182. @Test
  183. public void asyncTaskTest() throws InterruptedException, ExecutionException {
  184. long start = System.currentTimeMillis();
  185. Future<Boolean> asyncTask1 = task.asyncTask1();
  186. Future<Boolean> asyncTask2 = task.asyncTask2();
  187. Future<Boolean> asyncTask3 = task.asyncTask3();
  188. // 调用 get() 阻塞主线程
  189. asyncTask1.get();
  190. asyncTask2.get();
  191. asyncTask3.get();
  192. long end = System.currentTimeMillis();
  193. log.info("异步任务全部执行结束,总耗时:{} 毫秒", (end - start));
  194. }
  195. /**
  196. * 测试同步任务
  197. */
  198. @Test
  199. public void taskTest() throws InterruptedException {
  200. long start = System.currentTimeMillis();
  201. task.task1();
  202. task.task2();
  203. task.task3();
  204. long end = System.currentTimeMillis();
  205. log.info("同步任务全部执行结束,总耗时:{} 毫秒", (end - start));
  206. }
  207. }
  208. ```
  209. ## 运行结果
  210. ### 异步任务
  211. ```bash
  212. 2018-12-29 10:57:28.511 INFO 3134 --- [ async-task-3] com.xkcoding.async.task.TaskFactory : asyncTask3开始执行,当前线程名称【async-task-3】
  213. 2018-12-29 10:57:28.511 INFO 3134 --- [ async-task-1] com.xkcoding.async.task.TaskFactory : asyncTask1开始执行,当前线程名称【async-task-1】
  214. 2018-12-29 10:57:28.511 INFO 3134 --- [ async-task-2] com.xkcoding.async.task.TaskFactory : asyncTask2开始执行,当前线程名称【async-task-2】
  215. 2018-12-29 10:57:30.514 INFO 3134 --- [ async-task-2] com.xkcoding.async.task.TaskFactory : asyncTask2执行成功,当前线程名称【async-task-2】
  216. 2018-12-29 10:57:31.516 INFO 3134 --- [ async-task-3] com.xkcoding.async.task.TaskFactory : asyncTask3执行成功,当前线程名称【async-task-3】
  217. 2018-12-29 10:57:33.517 INFO 3134 --- [ async-task-1] com.xkcoding.async.task.TaskFactory : asyncTask1执行成功,当前线程名称【async-task-1】
  218. 2018-12-29 10:57:33.517 INFO 3134 --- [ main] com.xkcoding.async.task.TaskFactoryTest : 异步任务全部执行结束,总耗时:5015 毫秒
  219. ```
  220. ### 同步任务
  221. ```bash
  222. 2018-12-29 10:55:49.830 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task1开始执行,当前线程名称【main】
  223. 2018-12-29 10:55:54.834 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task1执行成功,当前线程名称【main】
  224. 2018-12-29 10:55:54.835 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task2开始执行,当前线程名称【main】
  225. 2018-12-29 10:55:56.839 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task2执行成功,当前线程名称【main】
  226. 2018-12-29 10:55:56.839 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task3开始执行,当前线程名称【main】
  227. 2018-12-29 10:55:59.843 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactory : task3执行成功,当前线程名称【main】
  228. 2018-12-29 10:55:59.843 INFO 3079 --- [ main] com.xkcoding.async.task.TaskFactoryTest : 同步任务全部执行结束,总耗时:10023 毫秒
  229. ```
  230. ## 参考
  231. - Spring Boot 异步任务线程池的配置 参考官方文档:https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-task-execution-scheduling

一个用来深度学习并实战 spring boot 的项目,目前总共包含 66 个集成demo,已经完成 55 个。