4

我正在使用该Executor框架Executors.newCachedThreadPool();
,我有一个Runnables 列表,例如 100。
前 50 个,每个创建一个值(存储在一个列表中)供最后 50 个使用。
我想如果我按顺序传递Runnablesexecutor.execute()它们在列表中,它们也将以相同的顺序执行。
但这并没有发生。
这些任务似乎是按随机顺序执行的,它们是交错的,而不是按顺序执行的。
这是它应该如何工作的吗?有什么办法可以解决这个问题?

谢谢

4

3 回答 3

10

您需要分两批提交作业,或者创建明确的“之前发生”关系。建议构建两批作业并使用invokeAll(batch1); invokeAll(batch2); 方法invokeAll()将执行所有任务并阻塞直到它们完成。您可能需要将Runnables 包装为Callables,您可以使用Executors.callable(Runnable r). (@Cameron Skinner 击败我获得了一些代码示例,请参阅该答案以获取更多信息......)

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

如果您详细说明您的具体应用,我们可能会提供更具体的帮助。

于 2010-12-17T12:39:48.380 回答
7

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

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

例如,

for (Future<Whatever> f: service.invokeAll(first50tasks)) {
    addResultToList(f.get());
}
Future<Whatever> output = service.invokeAll(second50tasks);
于 2010-12-17T12:43:53.430 回答
2

也许你可以execute前 50 个,shutdown然后awaitTermination,然后只有execute其他 50 个?有关一些示例代码,请参阅此答案

于 2010-12-17T12:40:13.187 回答