2014-05-22 16 views
4

在典型的JAVA应用程序中,配置用于管理全局线程池的全局ExecutorService。可以说,我配置100个线程的固定的线程池:仅使用ExecutorService中的线程子集

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); 

非常感谢,

安东尼

+0

你可以看看http://stackoverflow.com/q/19819837/2231632看看是否适用于你的情况?你不能单独使用信号量或某种锁存器来上传逻辑? – prabugp

+0

您提到的问题更多关于费率限制。我可以在我的客户代码中使用信号量,想知道是否有现成的设施来做这件事。 – lambdacalculus

+1

我认为典型的Java应用程序有许多线程池,其配置与它们的用例相匹配。所以我希望你的应用程序有一个单独的5线程线程池用于这个目的。 –

回答

1

在一个典型的Java程序,一个配置管理全局线程池全球的ExecutorService。

我没有这样做,但也许我是非典型的。 :-)回到你的问题:

由于具有防护(可能使用SemaphoreCallable的内线只会扰乱互相等待您的全球Executor哪些任务,你就必须要么

  • 使用一些外部逻辑确保只有5个作业在任何时候运行,这本身可以是一个Callable提交给你的一个Executor。这可以通过用一些逻辑包装你的下载作业来完成,这将从队列中提取下一个作业(包含网址或任何其他内容),然后您将这些“排水下载队列”作业中的五个提交到您的Executor并称之为完成。但我并不典型,我只是
  • 使用单独的Executor下载。这也让你能够适当地命名你的线程(在ExecutorThreadFactory),这可能有助于调试并制作漂亮的线程转储。
+0

我想我会与你的第一个提议,想知道是否有一些现有的设施这样做,像 'threadPool.createSubThreadpool(5)' – lambdacalculus

+1

我可以问为什么你只需要在你的程序中的一个'Executor'? – Waldheinz

+1

因为如果应用程序中的每个组件都使用自己的线程池,则不会对程序生成的线程总数有任何可见性。你可能会在不知情的情况下耗尽资源。 – lambdacalculus

相关问题