首页 > 解决方案 > CompletableFuture 总是抛出超时异常

问题描述

我有一段代码如下

protected List<AMQMessage> waitForReceivedRawMessageFromActiveMq(AMQConsumerMessageListener listener) {
CompletableFuture<List<AMQMessage>> completableFuture = CompletableFuture.supplyAsync(() -> {
    while (listener.getMessageList().isEmpty()) {}
    return listener.getMessageList();
});
List<AMQMessage> rawMessage = Lists.newLinkedList();
try {
    rawMessage = completableFuture.get(5000, TimeUnit.MILLISECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
    e.printStackTrace();
}
return rawMessage;
}

它总是抛出TimeoutException,我不知道发生了什么。但是当我在 IDEA 中切换调试点时,它就可以工作了。有没有人可以为我解释一下,pleaseeee。

标签: javajava-8completable-future

解决方案


这是由于同步不足而发生的。您正在更新某个线程中的listener's ,但正在运行您的线程(默认情况下为commonPool 的工作线程)没有看到该更改,因此循环将永远运行。有时它可能会看到这种变化,但不能保证。也许调试器以不同的方式处理线程的内存可见性。messageListsupplyAsync()ForkJoinwhile

解决方案:尝试添加synchronized到您的getMessageList()setMessageList()方法。和/或使用同步列表(如Collections.synchronizedList(...)orCopyOnWriteArrayList等​​),具体取决于您是更新列表变量的引用还是更新其内容。


推荐阅读