在一个典型的JAVA应用中,配置一个全局的ExecutorService来管理一个全局的线程池。假设我配置了一个包含 100 个线程的固定线程池:
ExecutorService threadPool = Executors.newFixedThreadPool(100);
现在假设我有一个包含 1000 个文件的列表要上传到服务器,对于每个上传我创建一个可调用函数来处理这个文件的上传。
List<Callable> uploadTasks = new ArrayList<Callable>();
// Fill the list with 1000 upload tasks
如何将并发上传的最大数量限制为 5 个?
如果我这样做
threadPool.invokeAll(uploadTasks);
我无法控制我的 1000 个任务将占用多少个线程。可能会并行运行 100 个上传,但我最多只需要 5 个。 我想创建某种子执行器,它使用父执行器的线程子集。 我不想为上传创建一个新的分离的 executorService,因为我想全局管理我的线程池。
你们中有人知道该怎么做吗,或者是否存在现有的实现?理想情况下是这样的
ExecutorService uploadThreadPool = Executors.createSubExecutor(threadPool,5);
非常感谢,
安托万
最佳答案
In a typical JAVA application, one configures a global ExecutorService for managing a global thread pool.
我不是这样做的,但也许我是非典型的。 :-) 回到你的问题:
因为有一个 guard (可能在你的 Callable
中使用 Semaphore
只会使你的全局 Executor
困惑,哪些任务相互等待,你必须要么
- 使用一些外部逻辑来确保任何时候只有 5 个作业在运行,它本身可以是一个
Callable
提交给您的一个Executor
。这可以通过使用一些逻辑包装您的下载作业来完成,一旦一个作业完成,这些逻辑就会从队列中拉出下一个作业(包含 URL 或其他内容)。然后,您将其中五个“耗尽下载队列”作业提交给您的Executor
并称之为完成。但是,尽管我很不典型,但我只是 - 使用单独的
Executor
进行下载。这也使您能够适本地命名您的线程(在Executor
的ThreadFactory
中),这可能有助于调试并进行良好的线程转储。
关于java - 仅使用 ExecutorService 中的线程子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23808541/