一个线程池Java的多个CompletionService
我正在使用以下体系结构开发Java服务器应用程序:一个线程池Java的多个CompletionService,java,concurrency,completion-service,Java,Concurrency,Completion Service,我正在使用以下体系结构开发Java服务器应用程序: 客户端向服务器发出RPC请求 我相信RPC服务器(gRPC)有自己的线程池来处理请求 请求会立即插入线程池1,以进行更多处理 我们将调用request R,一个特定的请求类型需要并行运行一些异步任务,判断结果以形成一个共识,即它将返回到客户端。这些任务的运行时间较长,因此我使用单独的线程池2来处理这些请求。重要的是,每个请求R都需要运行相同的2-3个异步任务线程池2因此为所有当前正在执行的请求R提供服务。但是,请求R应该只能查看和检索属于它的
- 客户端向服务器发出RPC请求
- 我相信RPC服务器(gRPC)有自己的线程池来处理请求
- 请求会立即插入
,以进行更多处理线程池1
- 我们将调用
,一个特定的请求类型需要并行运行一些异步任务,判断结果以形成一个共识,即它将返回到客户端。这些任务的运行时间较长,因此我使用单独的request R
来处理这些请求。重要的是,每个线程池2
都需要运行相同的2-3个异步任务<代码>线程池2因此为所有当前正在执行的请求R
提供服务。但是,请求R
应该只能查看和检索属于它的异步任务请求R
- 为了实现这一点,在每个传入的
时,当其位于请求R
中时,它将为请求创建一个新的线程池1
,由完成服务
支持。它将提交2-3个异步任务,并检索结果。这些请求应该与线程池2
中运行的属于其他请求的任何其他请求严格隔离线程池2
- 我的问题是:
- 首先,Java的
是孤立的吗?在检查了文档之后,我找不到关于这个的好文档。换句话说,如果两个或两个以上的CompletionService
由同一线程池支持,它们中的任何一个是否有可能拖累属于另一个CompletionService
的未来CompletionService
- 其次,为每个请求创建这么多的
,这是一种糟糕的做法吗?有没有更好的方法来处理这个问题?当然,为每个请求创建一个新的线程池不是一个好主意,那么有没有更规范/正确的方法来隔离CompletionService
中的未来,或者我正在做的事情还好吗CompletionService
- 首先,Java的
公共静态最终执行器服务线程池2=
新的ThreadPoolExecutor(16,64,60,TimeUnit.SECONDS,新的LinkedBlockingQueue());
//为处理请求程序而创建,RequestRHandler在线程池1中运行
公共类请求处理程序{
完成服务cs;
RequestRHandler(){
cs=新的ExecutorCompletionService(线程池2);
}
字符串执行(){
提交(1);
提交(2);
提交(3);
//假设asyncTask3首先完成
Future asyncTask3Result=cs.take();
//asyncTask3结果表示asyncTask1和asyncTask2结果无所谓,请取消它们
//没有检查结果
//取消所有期货,我跟踪此请求中提交的所有期货并取消它们,
//因此,它不应该影响tp2池中的任何其他请求
取消所有期货(cs);
返回asyncTask3Result.get();
}
}
首先,Java的CompletionService
是孤立的吗
这不是保证,因为它是一个接口,所以由实现决定。但由于唯一的实现是ExecutorCompletionService
,我只能说答案是:是的。ExecutorCompletionService
的每个实例在内部都有一个BlockingQueue
,完成的任务在这里排队。实际上,当您在服务上调用take
时,它只是通过调用take
将调用传递给队列。每个提交的任务都由另一个对象包装,该对象在任务完成时将任务放入队列。因此,每个实例都独立于其他实例管理其提交的任务
其次,为每个请求创建这么多的CompletionService
s,这是一种糟糕的做法吗
我得说没关系。CompletionService
不过是围绕执行者的一个相当薄的包装。您必须承受“开销”(任务的内部BlockingQueue
和包装器实例),但它很小,而且您可能从中获得的比成本更多。有人可能会问,你是否需要一个只用于2到3项任务,但这取决于任务。在这一点上,这是一个关于CompletionService
是否值得的问题,所以这取决于您的决定,因为它超出了您的问题范围