Java CompletableFuture始终抛出超时异常
我有一段代码如下Java CompletableFuture始终抛出超时异常,java,java-8,completable-future,Java,Java 8,Completable Future,我有一段代码如下 受保护列表waitForReceivedRawMessageFromActiveMq(AMQConsumerMessageListener侦听器){ CompletableFuture CompletableFuture=CompletableFuture.supplyAsync(()->{ 而(listener.getMessageList().isEmpty()){} 返回listener.getMessageList(); }); List rawMessage=List
受保护列表waitForReceivedRawMessageFromActiveMq(AMQConsumerMessageListener侦听器){
CompletableFuture CompletableFuture=CompletableFuture.supplyAsync(()->{
而(listener.getMessageList().isEmpty()){}
返回listener.getMessageList();
});
List rawMessage=Lists.newLinkedList();
试一试{
rawMessage=completableFuture.get(5000,时间单位为毫秒);
}捕获(InterruptedException | ExecutionException | TimeoutException e){
e、 printStackTrace();
}
返回消息;
}
它总是抛出TimeoutException
,我不知道发生了什么。
但当我在IDEA中切换调试点时,它就工作了。
有没有人能为我解释一下,拜托。这是因为同步不足。您正在某些线程中更新
侦听器的消息列表,但是运行supplyAsync()
的线程(默认情况下,ForkJoin
commonPool的工作线程)看不到该更改,因此while
循环将永远运行。有时,它可能会看到这种变化,但这并不能保证。调试器处理线程内存可见性的方式可能不同
解决方案:尝试将synchronized
添加到getMessageList()
和setMessageList()
方法中。和/或使用同步列表(如Collections.synchronizedList(…)
或CopyOnWriteArrayList
等),这取决于您是更新列表变量的引用还是更新其内容。您到底在使用调试器做什么?我在return listener.getMessageList()行中添加了调试点代码>和以上代码工作正常。您具体做什么。在那一行设置断点,调试程序。那么断点命中了吗?没错。但是当我关闭断点时,上面的代码就不再工作了。什么是AMQConsumerMessageListener
?现在这个问题是没有意义的,投票结束。你能和我分享一篇关于它的文章吗。实际上,我不知道它们的机制。你可能是对的,但如果不知道AMQConsumerMessageListener是什么或做什么,你就不能简单地假设将synchronized添加到这些方法中(这可能太多了,在适当的位置进行volatile
读/写就足够了)会做正确的事情。