【发布时间】:2020-10-20 05:15:21
【问题描述】:
我正在开发具有以下一般架构的 Java 服务器应用程序:
- 客户端向服务器发出 RPC 请求
- 我相信 RPC 服务器 (gRPC) 有自己的线程池来处理请求
- 请求会立即插入
Thread Pool 1以进行更多处理 - 一个具体的请求类型,我们叫
Request R,需要并行运行几个异步任务,判断结果形成共识,返回给客户端。这些任务运行时间较长,因此我使用单独的Thread Pool 2来处理这些请求。重要的是,每个Request R都需要运行相同的 2-3 个异步任务。Thread Pool 2因此服务于所有当前正在执行Request R的服务。但是,Request R应该只能查看和检索属于它的异步任务。 - 为了实现这一点,在每个传入的
Request R中,当它在Thread Pool 1中时,它将为请求创建一个新的CompletionService,由Thread Pool 2支持。它将提交 2-3 个异步任务,并检索结果。这些应与Thread Pool 2中可能运行的属于其他请求的任何其他内容严格隔离。 - 我的问题:
- 首先,Java 的
CompletionService是隔离的吗?检查JavaDocs 后,我找不到关于此的好的文档。换句话说,如果两个或更多CompletionService由 same 线程池支持,它们中的任何一个是否有可能将未来拉到另一个CompletionService上? - 其次,为每个请求创建这么多
CompletionService是不是不好?有没有更好的方法来处理这个?当然,为每个请求创建一个新的线程池是一个坏主意,那么有没有更规范/正确的方法来隔离CompletionService中的期货,或者我正在做的事情好吗?
- 首先,Java 的
提前感谢您的帮助。任何指向有用的文档或示例的指针将不胜感激。
代码,供参考,虽然琐碎:
public static final ExecutorService THREAD_POOL_2 =
new ThreadPoolExecutor(16, 64, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
// Gets created to handle a RequestR, RequestRHandler is run in Thread Pool 1
public class RequestRHandler {
CompletionService<String> cs;
RequestRHandler() {
cs = new ExecutorCompletionService<>(THREAD_POOL_2);
}
String execute() {
cs.submit(asyncTask1);
cs.submit(asyncTask2);
cs.submit(asyncTask3);
// Lets say asyncTask3 completes first
Future<String> asyncTask3Result = cs.take();
// asyncTask3 result indicates asyncTask1 & asyncTask2 results don't matter, cancel them
// without checking result
// Cancels all futures, I track all futures submitted within this request and cancel them,
// so it shouldn't affect any other requests in the TP 2 pool
cancelAllFutures(cs);
return asyncTask3Result.get();
}
}
【问题讨论】:
标签: java concurrency completion-service