我正在开发具有以下一般架构的 Java 服务器应用程序:
- 客户端向服务器发出 RPC 请求
- 我相信 RPC 服务器(gRPC)有自己的线程池来处理请求
- 请求立即插入以
Thread Pool 1
进行更多处理 - 一个特定的请求类型,我们称之为
Request R
,需要并行运行几个异步任务,判断结果形成共识,返回给客户端。这些任务运行时间更长一些,所以我使用单独Thread Pool 2
的来处理这些请求。重要的是,每个Request R
都需要运行相同的 2-3 个异步任务。Thread Pool 2
因此服务所有当前正在执行Request R
的。但是,aRequest R
应该只能查看和检索属于它的异步任务。 - 为了实现这一点,在每次传入
Request R
时,当它进入时Thread Pool 1
,它将CompletionService
为请求创建一个新的,由Thread Pool 2
. 它将提交 2-3 个异步任务,并检索结果。这些应该与可能运行在Thread Pool 2
属于其他请求的任何其他内容严格隔离。 - 我的问题:
- 首先,Java 是
CompletionService
孤立的吗?检查JavaDocs后,我找不到关于此的好的文档。换句话说,如果两个或多个CompletionService
's 由同一个线程池支持,它们中的任何一个是否有可能将未来拉到另一个s 上CompletionService
? CompletionService
其次,为每个请求创建这么多的这是不好的做法吗?有没有更好的方法来处理这个?当然,为每个请求创建一个新的线程池是一个坏主意,那么有没有更规范/正确的方法来隔离 a 中的期货,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();
}
}