CompletableFuture 总是抛出超时异常
CompletableFuture always throw time out exception
我有一段代码如下
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 中切换调试点时,它就可以工作了。
有没有人可以帮我解释一下,拜托。
发生这种情况是因为同步不足。您正在某个线程中更新 listener
的 messageList
,但是 运行 您的 supplyAsync()
的线程(默认情况下 ForkJoin
commonPool 的工作线程)没有' 看到那个变化,所以 while
循环永远运行。有时它 可能 看到该变化,但不能保证。也许调试器以不同方式处理线程的内存可见性。
解决方案:尝试将 synchronized
添加到您的 getMessageList()
和 setMessageList()
方法中。 And/or 使用同步列表(如 Collections.synchronizedList(...)
或 CopyOnWriteArrayList
等),具体取决于您是更新列表变量的引用,还是更新其内容。
我有一段代码如下
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 中切换调试点时,它就可以工作了。
有没有人可以帮我解释一下,拜托。
发生这种情况是因为同步不足。您正在某个线程中更新 listener
的 messageList
,但是 运行 您的 supplyAsync()
的线程(默认情况下 ForkJoin
commonPool 的工作线程)没有' 看到那个变化,所以 while
循环永远运行。有时它 可能 看到该变化,但不能保证。也许调试器以不同方式处理线程的内存可见性。
解决方案:尝试将 synchronized
添加到您的 getMessageList()
和 setMessageList()
方法中。 And/or 使用同步列表(如 Collections.synchronizedList(...)
或 CopyOnWriteArrayList
等),具体取决于您是更新列表变量的引用,还是更新其内容。