我正在开发一个具有以下一般架构的Java服务器应用程序:
Thread Pool 1以进行更多处理。Request R,需要并行运行几个异步任务,判断结果以形成一个共识,即它将返回给客户端。这些任务运行时间较长,因此我使用单独的Thread Pool 2来处理这些请求。重要的是,每个Request R都需要运行相同的2-3个异步任务。因此,Thread Pool 2服务于所有当前正在执行的Request R。然而,Request R只应该能够看到和检索属于它的异步任务。Request R上,而在Thread Pool 1中,它将为请求创建一个由Thread Pool 2支持的新CompletionService。它将提交2-3个异步任务,并检索结果。应该严格地将它们与其他属于其他请求的Thread Pool 2中可能运行的任何东西隔离开来。CompletionService是孤立的吗?在检查了JavaDocs之后,我找不到关于这方面的好文档。换句话说,如果两个或多个CompletionService由相同的线程池支持,那么它们中的任何一个是否有可能提取属于另一个CompletionService的未来?CompletionService是一种糟糕的做法吗?是否有更好的方法来处理这个问题?当然,为每个请求创建一个新的线程池是个坏主意,那么在CompletionService中是否有一种更规范/更正确的方法来隔离未来,或者我的做法还好吗?提前谢谢你的帮助。任何有帮助的文档或检查的指针都将不胜感激。
代码,以供参考,尽管是微不足道的:
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();
}
}发布于 2020-06-30 02:14:08
首先,Java的
CompletionService是孤立的吗?
这不是固定的,因为它是一个接口,所以实现决定了。但是,由于唯一的实现是ExecutorCompletionService,我只想说答案是:是的。ExecutorCompletionService的每个实例在内部都有一个BlockingQueue,其中已完成的任务在其中排队。实际上,当您在服务上调用take时,它只是通过调用队列上的take将调用传递给队列。每个提交的任务都由另一个对象包装,该对象在任务完成时将任务放在队列中。因此,每个实例都管理它从其他实例中分离出来的提交任务。
第二,为每个请求创建这么多
CompletionService是一种错误的做法吗?
我会说没关系的。CompletionService只不过是一个很薄的执行器包装器。您必须忍受“开销”(任务的内部BlockingQueue和包装器实例),但是它很小,而且您可能从它获得的收益超过了它的成本。如果你只需要2到3个任务,你可能会问你是否需要一个,但这在一定程度上取决于任务。在这一点上,这是一个关于CompletionService是否值得这样做的问题,所以这取决于您的决定,因为它超出了您的问题范围。
https://stackoverflow.com/questions/62648336
复制相似问题