4

Java ExecutorService 框架允许您使用托管线程池委派要执行的多个任务,以便可以一次执行 N 个任务,直到完成 X 个任务。

我的问题是......如果 N 是一个无限大的数字,以至于最初分配/分配/定义不切实际怎么办。

您如何利用 Java (ExecutorService) 中的线程池概念来处理比您可以合理提交的任务更多的任务,而不会耗尽资源。

出于此答案的目的,假设每个任务都是独立的,不依赖于任何其他任务,并且任务可以按任意顺序完成。

我最初尝试解决这个问题涉及一次提供 ExecutorService Y 个线程,但我很快意识到没有明显的方法可以判断特定任务何时完成,因此无法提交要执行的新任务。

我知道我可以编写自己的“ExecutorService”,但我正在尝试利用 Java 框架已经提供的丰富功能。我通常属于“不要重新发明轮子”类别,因为比我更聪明的人已经为我进行了投资。

提前感谢任何可以提供有关如何解决此类问题的任何见解的人。

4

2 回答 2

3

你可以使用 aCompletionService来做到这一点。您可以有一个线程为服务提供一堆任务,然后在任务完成时添加新任务。

一个简单的例子:

final CompletionService service = new ExecutorCompletionService(Executors.newFixedThreadPool(5));
Runnable taskGenerator = new Runnable() {
    public void run() {
        // Seed the service
        for (int i = 0; i < 100; ++i) {
            service.submit(createNewTask());
        }
        // As tasks complete create new ones
        while (true) {
            Future<Something> result = service.take();
            processResult(result.get());
            service.submit(createNewTask());
        }
    }
};
new Thread(taskGenerator).start();

这使用一个ThreadPoolExecutor带有 5 个线程来处理任务和一个手动生产者/消费者线程来生成任务和处理结果。

显然,您需要比 更智能的东西while (true),您需要对 and 进行合理的实现processResultcreateNewTask并且假设任务执行比生成它们或处理结果要慢得多。

希望这会让你走上正轨。

于 2012-12-09T01:11:29.943 回答
0

使用 java.util.concurrent.ThreadPoolExecutor 和 java.util.concurrent.ArrayBlockingQueue 作为它的 workQueue。这种方式尝试放置比队列大小更多的任务会阻塞。

  BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<Runnable>(100);
  ThreadPoolExecutor tpe=new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, workQueue);

  while (true) {
     tpe.execute(createNewTask());
  }
于 2012-12-09T02:25:18.730 回答