spring@Async异步获取结果
涉及到两个问题:
- 解决同类调用@Async方法无效问题。
- 用completableFuture替换Future,解决Future.get()获取结果阻塞的问题。
这里只提供利用@Async注解的解决方案,因为使用了spring,更倾向于用spring的注解来解决问题.把线程池注册成bean交给spring管理,比自己每次生成销毁或者自己控制全局线程池要优雅的多.
另一种解决方案,因为线程池是通过@bean方式注册成bean,直接@autowied线程池,然后利用正常的线程池+countDownLatch也可以解决(未验证)。
以下是基于@async的解决方案:
代码不连续,这里只贴一下关键代码,以免非关键代码干扰思路,不懂的留言或者邮件我cheyantao@foxmail.com,看见了及时回你。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| . . .
@Autowired private ApplicationContext applicationContext; . . .
public Page<SourceVo> page(Pageable pageable, String selectId, String keyword) { . . CountDownLatch countDownLatch = new CountDownLatch(sourceDo.getContent().size()); for (Source source : sourceDo.getContent()) { . . . SourceService serviceProxy = applicationContext.getBean(SourceService.class); serviceProxy .requestDataByte(source, component) .thenAccept( s -> { sourceVo.setDataByte(s); content.add(sourceVo); countDownLatch.countDown(); }); } try { countDownLatch.await(5, TimeUnit.SECONDS); } catch (InterruptedException e) { log.error("获取数据量线程阻塞异常", e); } } . . .
@Override @Async("fetchExecutor") public CompletableFuture<String> requestDataByte(Source source, Component component) { String metricName = this.buildMetricNames(source); if (StringUtils.isBlank(metricName)) { return AsyncResult.forValue("").completable(); } try { . . . return AsyncResult.forValue(this.getValueFromMetric(response.getMetrics().get(0))) .completable(); } catch (Exception ex) { log.error("获取数据量失败,sourceId:{}", source.getId(), ex); return AsyncResult.forValue("").completable(); } }
|
OK ,以上.