Java ExecutorService框架允许您使用托管线程池委派要执行的许多任务,以便可以一次执行X个任务,直到完成为止。
我的问题是......如果N是一个无限大的数字,或者最初分配/赋值/定义是不切实际的。
如何利用Java(ExecutorService)中的线程池概念来处理比合理提交的任务更多的任务,而不会耗尽资源。
出于本答案的目的,假设每个任务都是自包含的,并且不依赖于任何其他任务,并且任务可以按任意顺序完成。
我最初尝试攻击此问题涉及一次提供ExecutorService Y线程,但我很快意识到没有明显的方法来判断特定任务何时完成,因此提交了一个新任务要执行。
我知道我可以编写自己的“ExecutorService”,但我正在尝试利用Java框架已经提供的内容。我一般都在“不要重新发明轮子”类别,因为比我更多的思想已经为我做了投资。
提前感谢能够提供有关如何解决此类问题的任何见解的人。
答案 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)
更聪明的东西,你需要有processResult
和createNewTask
的合理实现,这假设任务执行比生成它们或处理结果。
希望这会让你走上正轨。
答案 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());
}