Java:在一个链中组合几个可完成的未来
我希望有一个方法来发送请求,然后通过UDP接收响应。 以下是我目前的发展:Java:在一个链中组合几个可完成的未来,java,completable-future,Java,Completable Future,我希望有一个方法来发送请求,然后通过UDP接收响应。 以下是我目前的发展: public <T extends ObjectSerializable, U extends ObjectDeserializable> CompletableFuture<Object> execute(T request, U response) { var resultFuture = sender.asyncSend(request); /*CompletableFuture&l
public <T extends ObjectSerializable, U extends ObjectDeserializable>
CompletableFuture<Object> execute(T request, U response)
{
var resultFuture = sender.asyncSend(request); /*CompletableFuture<Void>*/
resultFuture.thenAccept((nullObj) -> {
try {
receiver.asyncReceive(response).get(); /*CompletableFuture<Void>*/
}catch (Exception e) {
throw new FutureExecutionException(e.getMessage());
}
}).thenRun(() -> {
System.out.println("Send->Receive finished");
});
return resultFuture;
}
公共
CompletableFuture执行(T请求,U响应)
{
var resultFuture=sender.asyncSend(请求);/*CompletableFuture*/
结果未来。然后接受((nullObj)->{
试一试{
receiver.asyncReceive(response.get();/*CompletableFuture*/
}捕获(例外e){
抛出新的FutureExecutionException(例如getMessage());
}
}).然后运行(()->{
System.out.println(“发送->接收完成”);
});
返回结果未来;
}
问题是:我是否必须在内等待未来。然后接受?是否保证在receiver.asyncReceive完成后执行.thenRun
?
我这样组合CompletableFutures是否正确?这是一个看起来不错的解决方案
public <T extends ObjectSerializable, U extends ObjectDeserializable>
CompletableFuture<Void> execute(T request, U response)
{
return sender.asyncSend(request)
.thenCompose( result -> receiver.asyncReceive(response))
.thenRun( () -> System.out.println("Send-Receive finished"));
}
公共
CompletableFuture执行(T请求,U响应)
{
返回发送者。异步发送(请求)
.thenCompose(结果->接收方.asyncReceive(响应))
.then运行(()->System.out.println(“发送-接收完成”);
}
如果您的execute
将类
作为参数,那么这将容易得多。然后您可以将该类传递给receiver.asyncReceive
。在内部,您可以(假设这样的类有一个默认构造函数)创建一个实例并用所有字段填充它。这很容易通过以下途径实现:
clazz.getConstructor().newInstance()
然后,您的代码将返回一个CompletableFuture
,因此您的方法将类似于:
public <T extends ObjectSerializable, U extends ObjectDeserializable>
CompletableFuture<U> execute(T request, Class<U> response){
return sender.asyncSend(request)
.thenCompose(nothing -> receiver.asyncReceive(response));
}
公共
CompletableFuture执行(T请求、类响应){
返回发送者。异步发送(请求)
.thenCompose(nothing->receiver.asyncReceive(response));
}
我也不确定您的asyncSend
是否应该返回一个CompletableFuture
,可能这个函数也可以将类
作为参数,并返回正确的类型作为CompletableFuture
,但是您不需要asyncReceive
,我想…我希望有一个方法来发送请求,然后通过UDP接收响应,但这里您返回一个CompletableFuture
,您不知道它是否已完成。这就是你想要的吗?是的,因为稍后我会简单地调用。获取并检索响应对象。如果超时,我会得到ExecutionException。如果您对完整的源代码感兴趣,我可以直接与您共享。什么响应对象?调用阻塞get
时,您将得到一个空值。另外,方法名没有任何意义,它没有潜在地执行任何东西。它可以执行,但只有当发送方.asyncSend(请求)
在之前准备就绪时,它才能执行。然后将compose(result->receiver.asyncsreceive(response))
附加到以前的将来。get向我保证响应对象已经在接收方内部反序列化,我可以安全地访问它。据我所知,thenCompose只有在前一个未来还可以的情况下才会执行,我错了吗?至少我的测试显示了这种行为你有很多我没有的背景。与返回类型相反,response
作为execute
方法的参数是非常奇怪的。。。似乎您的receiver.asyncReceive(response)
正在某个地方存储响应,因此当您稍后调用get
并成功时,您将从“某个地方”获得响应。不