简体   繁体   English

ThreadPool不会按顺序运行任务

[英]ThreadPool does not run tasks in sequence

I am using the Executor framework specifically Executors.newCachedThreadPool(); 我正在使用Executor框架专门Executors.newCachedThreadPool();
I have a list of Runnable s eg 100. 我有一个Runnable的列表,例如100。
The first 50, each create a value (stored in a list) to be used by the last 50. 前50个,每个创建一个值(存储在列表中)以供最后50个使用。
I thought that if I pass the Runnable s in the executor.execute() in the order they are in the list, they would be also executed in the same order. 我想如果我按照它们在列表中的顺序在executor.execute()中传递Runnable ,它们也将以相同的顺序执行。
But this is not happening. 但这不会发生。
The tasks seem to be executed in random order and they are interleaved, not executed in sequence. 这些任务似乎是以随机顺序执行的,它们是交错的,不是按顺序执行的。
Is this how it is suppose to work? 这是假设工作的方式吗? Any way to work around this problem? 有办法解决这个问题吗?

Thanks 谢谢

You need to submit the jobs in two batches, or otherwise create an explicit "happens-before" relationship. 您需要分两批提交作业,或者以其他方式创建明确的“先发生”关系。 Suggest building two batches of jobs and using invokeAll(batch1); invokeAll(batch2); 建议构建两批作业并使用invokeAll(batch1); invokeAll(batch2); invokeAll(batch1); invokeAll(batch2); The invokeAll() method will execute all of the tasks and block until they complete. invokeAll()方法将执行所有任务并阻塞,直到它们完成。 You may need to wrap your Runnable s as Callable s, which you can do with Executors.callable(Runnable r) . 您可能需要将Runnable包装为Callable ,您可以使用Executors.callable(Runnable r) (@Cameron Skinner beat me to getting some code example, see that answer for more...) (@Cameron Skinner打败我以获得一些代码示例,看到更多的答案...)

The whole point of executors is to abstract away the specifics of execution, so ordering is not guaranteed unless explicitly stated. 执行者的全部意义是抽象出执行的具体细节,因此除非明确说明,否则不能保证订购。 If you want strictly sequential execution, do it in the thread you're running in (simplest), do it in a single-threaded executor, ala Executors.newSingleThreadExecutor() , or explicitly synchronize the tasks. 如果您想要严格顺序执行,请在您运行的线程(最简单)中执行,在单线程执行程序,ala Executors.newSingleThreadExecutor() ,或显式同步任务。 If you want to do the latter, you could use a barrier or latch and have the dependent tasks block on the barrier/latch. 如果要执行后者,可以使用屏障或锁存器,并在屏障/锁存器上阻止相关任务。 You could also have the first block of tasks implement Callable , return Future , and have the dependent tasks call myFuture.get() which would cause them to block until the results are returned. 您还可以让第一个任务块实现Callable ,返回Future ,并让依赖任务调用myFuture.get() ,这将导致它们阻塞,直到返回结果。

If you say more about your specific application, we might be able to help more specifically. 如果您更多地了解您的具体应用,我们可能会更具体地提供帮助。

That is the correct behaviour. 这是正确的行为。 You have no guarantees about which order the Runnables are executed. 您无法保证Runnables的执行顺序。

Executors run in parallel , whereas it seems that you want the tasks run in serial . 执行程序并行运行,而您似乎希望任务以串行方式运行。 You can either submit the first 50 jobs, wait for them to finish, then submit the second 50 jobs, or (if the order of execution is important) just run them all in a single thread. 您可以提交前50个作业,等待它们完成,然后提交第二个50个作业,或者(如果执行顺序很重要)只需在一个线程中运行它们。

For example, 例如,

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

Perhaps you could execute the first 50, shutdown and awaitTermination , and only then execute the other 50? 也许你可以execute前50, shutdownawaitTermination ,然后再execute其他50? See this answer for some sample code. 有关示例代码,请参阅此答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM