如何使用Java ExecutorService线程池进行持续/无限任务?

时间:2012-12-09 00:44:43

标签: java concurrency

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

我的问题是......如果N是一个无限大的数字,或者最初分配/赋值/定义是不切实际的。

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

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

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

我知道我可以编写自己的“ExecutorService”,但我正在尝试利用Java框架已经提供的内容。我一般都在“不要重新发明轮子”类别,因为比我更多的思想已经为我做了投资。

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

2 个答案:

答案 0 :(得分:3)

您可以使用CompletionService来执行此操作。你可以有一个线程通过一堆任务来为服务提供种子,然后当任务完成时你可以添加新的任务。

一个简单的例子:

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

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

显然你会想要比while (true)更聪明的东西,你需要有processResultcreateNewTask的合理实现,这假设任务执行比生成它们或处理结果。

希望这会让你走上正轨。

答案 1 :(得分: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());
  }