completablefuture总是抛出超时异常

gfttwv5a  于 2021-07-11  发布在  Java
关注(0)|答案(1)|浏览(802)

我有一段代码如下

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 ,我不知道发生了什么。但当我在想法中切换调试点时,它就工作了。有人能为我解释一下吗。

68bkxrlz

68bkxrlz1#

发生这种情况是因为同步不足。您正在更新 listenermessageList 在某个线程中,但是运行 supplyAsync() (the) ForkJoin commonpool的工作线程(默认情况下)看不到该更改,因此 while 循环永远运行。有时它可能会看到这种变化,但这并不能保证。也许调试器处理线程的内存可见性的方式不同。
解决方案:尝试添加 synchronized 给你的 getMessageList() 以及 setMessageList() 方法。和/或使用同步列表(如 Collections.synchronizedList(...) 或者 CopyOnWriteArrayList ,这取决于您是更新列表变量的引用,还是更新其内容。

相关问题