【发布时间】:2023-03-07 19:21:01
【问题描述】:
我有一组要处理的记录,并且可以并行处理,所以我创建了一个ExecutorService(通过Executors#newCachedThreadPool())。单个记录的处理本身是由可并行化的步骤组成的,所以我想使用另一个ExecutorService。有没有一种简单的方法可以让这个新线程使用相同的底层线程池?它甚至是可取的吗?谢谢。
【问题讨论】:
标签: java concurrency threadpool
我有一组要处理的记录,并且可以并行处理,所以我创建了一个ExecutorService(通过Executors#newCachedThreadPool())。单个记录的处理本身是由可并行化的步骤组成的,所以我想使用另一个ExecutorService。有没有一种简单的方法可以让这个新线程使用相同的底层线程池?它甚至是可取的吗?谢谢。
【问题讨论】:
标签: java concurrency threadpool
回答您的问题:否,两个ExecutorService 对象不能共享一个线程池。但是,您可以在对象之间共享 ExecutorService,或者根据需要创建多个 Executor,尽管不太推荐这样做。
最佳解决方案:在您的对象之间共享Executor。
【讨论】:
简短回答:不。
更长的答案:您需要自己的实现来做到这一点。 ExecutorService 是一个接口,AbstractExecutorService 很容易实现。
如果你想让两个ExecutorService共享同一个线程池(例如具有不同的最大活跃线程值),你可以使用代理模式使线程池共享ExecutorService。
【讨论】:
您可以将现有 ExecutorService 的引用传递给您的工作对象吗?
public class Task implements Runnable {
private final ExecutorService threadPool;
private final SubTask[] subtasks;
public Task(ExecutorService threadPool) {
this.threadPool = threadPool;
this.subtasks = createSubtasksIGuess();
}
public void run() {
for(SubTask sub : subtasks)
threadPool.submit(sub);
}
}
【讨论】:
有几个很好的理由想要这样做,例如每个队列的单独边界和指标。 AFAIK,Cassandra 2.1 通过使用具有共享线程池的执行器服务实现获得了不小的好处;代码位于https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/concurrent/SEPExecutor.java。
【讨论】:
AbortPolicy,另一个使用CallerRunsPolicy。