ThreadPool不会按顺序运行任务

时间:2010-12-17 12:35:03

标签: java multithreading executorservice executor

我专门使用Executor框架Executors.newCachedThreadPool();
我有一个Runnable的列表,例如100.
前50个,每个创建一个值(存储在列表中)以供最后50个使用 我想如果我按照它们在列表中的顺序传递Runnable中的executor.execute() s,它们将是 也按同一顺序执行 但这种情况并没有发生 这些任务似乎是以随机顺序执行的,它们是交错的,不是按顺序执行的 这是假设工作的方式吗?有什么方法可以解决这个问题吗?

由于

3 个答案:

答案 0 :(得分:10)

您需要分两批提交作业,或以其他方式创建明确的“事先发生”关系。建议构建两批作业并使用invokeAll(batch1); invokeAll(batch2); invokeAll()方法将执行所有任务并阻止它们完成。您可能需要将Runnable包裹为Callable s,您可以使用Executors.callable(Runnable r)。 (@Cameron Skinner打败我以获得一些代码示例,看到更多的答案......)

执行者的全部意义是抽象出执行的具体细节,因此除非明确说明,否则不能保证订购。如果您想要严格顺序执行,请在您运行的线程(最简单)中执行,在单线程执行程序,ala Executors.newSingleThreadExecutor()中执行,或明确同步任务。如果要执行后者,可以使用屏障或锁存器,并在屏障/锁存器上阻止相关任务。您还可以让第一个任务块实现Callable,返回Future,并让相关任务调用myFuture.get(),这将导致它们阻塞,直到返回结果。

如果您更多地了解您的具体应用,我们可能会更具体地提供帮助。

答案 1 :(得分:7)

这是正确的行为。您无法保证Runnables的执行顺序。

执行程序在 parallel 中运行,而您似乎希望任务在 serial 中运行。您可以提交前50个作业,等待它们完成,然后提交第二个50个作业,或者(如果执行顺序很重要)只需在一个线程中运行它们。

例如,

for (Future<Whatever> f: service.invokeAll(first50tasks)) {
    addResultToList(f.get());
}
Future<Whatever> output = service.invokeAll(second50tasks);

答案 2 :(得分:2)

也许你可以execute前50,shutdownawaitTermination,然后只有execute其他50?有关示例代码,请参阅this answer