另外,从上面的运行结果可以看出,当所有任务执行完成之后才返回结果。这种情况对应于我们需要返回结果给客户端请求的情况下,假如我们不需要返回任务执行结果给客户端的话呢? 就比如我们上传一个大文件到系统,上传之后只要大文件格式符合要求我们就上传成功。普通情况下我们需要等待文件上传完毕再返回给用户消息,但是这样会很慢。采用异步的话,当用户上传之后就立马返回给用户消息,然后系统再默默去处理上传任务。这样也会增加一点麻烦,因为文件可能会上传失败,所以系统也需要一点机制来补偿这个问题,比如当上传遇到问题的时候,发消息通知用户。
下面会演示一下客户端不需要返回结果的情况:
将completableFutureTask方法变为 void 类型
- @Async
- public void completableFutureTask(String start) {
- ......
- //这里可能是系统对任务执行结果的处理,比如存入到数据库等等......
- //doSomeThingWithResults(results);
- }
Controller 代码修改如下:
- @GetMapping("/movies")
- public String completableFutureTask() throws ExecutionException, InterruptedException {
- // Start the clock
- long start = System.currentTimeMillis();
- // Kick of multiple, asynchronous lookups
- List<String> words = Arrays.asList("F", "T", "S", "Z", "J", "C");
- words.stream()
- .forEach(word -> asyncService.completableFutureTask(word));
- // Wait until they are all done
- // Print results, including elapsed time
- System.out.println("Elapsed time: " + (System.currentTimeMillis() - start));
- return "Done";
- }
请求这个接口,控制台打印出下面的内容:
- Elapsed time: 0
- 2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-4] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-4start this task!
- 2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-3] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-3start this task!
- 2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-2] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-2start this task!
- 2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-1] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-1start this task!
- 2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-6] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-6start this task!
- 2019-10-01 14:02:44.052 WARN 19051 --- [lTaskExecutor-5] g.j.a.service.AsyncService : My ThreadPoolTaskExecutor-5start this task!
可以看到系统会直接返回给用户结果,然后系统才真正开始执行任务。
待办
- Future vs. CompletableFuture
- 源代码分析
(编辑:ASP站长网)
|