这个问题可能更多是关于集成模式,而不是关于多线程。但是可以使用异步调用和观察者模式的组合来编排同一应用程序/JVM 中的请求:
最好使用示例(利用您的 Java 知识)来完成此操作。检查以下尝试复制您的场景的简单组件:
第三方服务:它暴露了一个返回关联ID并开始长时间运行的操作
class ExternalService {
public String send() {
return UUID.randomUUID().toString();
}
}
您的面向客户端的服务:它接收请求,调用第三方服务,然后在向结果接收器注册后等待响应:
class RequestProcessor {
public Object submitRequest() {
String correlationId = new ExternalService().send();
return new ResultReceiver().register(correlationId).join();
}
}
结果接收者:它向第三方服务公开一个操作,并维护一个内部相关注册表:
class ResultReceiver {
Map<String, CompletableFuture<Object>> subscribers;
CompletableFuture<Object> register(String responseId) {
CompletableFuture<Object> future = new CompletableFuture<Object>();
this.subscribers.put(responseId, future);
return future;
}
public void externalResponse(String responseId, Object result) {
this.subscribers.get(responseId).complete(result);
}
}
在这种情况下,期货、承诺、回调很方便。同步由初始请求处理器完成,以强制执行阻塞客户端。
现在,这可能会引发一些在这个简单的类集中没有解决的问题。其中一些问题可能是:
new ExternalService().send()
和之间的竞争条件new ResultReceiver().register(correlationId)
。ResultReceiver
如果不知道某些响应可能非常快(可以说是2路等待),这是可以解决的
永远不会出现的结果:结果可能需要很长时间或只是遇到错误。这些未来的 API 通常会提供超时来强制取消请求。例如:
new ResultReceiver().register(correlationId)
.get(10000, TimeUnit.SECONDS);