问题描述
我正在专门使用Executor
框架Executors.newCachedThreadPool();
我有一个Runnable
的列表,例如100.
前50个,每个都会创建一个值(存储在列表中),供后50个使用.
我以为如果我按列表中的顺序通过executor.execute()
中的Runnable
,它们将是也以相同的顺序执行.
但这没有发生.
任务似乎是随机执行的,它们是交错的,而不是按顺序执行.
这是应该工作的方式吗?有什么办法解决这个问题?
I am using the Executor
framework specifically Executors.newCachedThreadPool();
I have a list of Runnable
s e.g. 100.
The first 50, each create a value (stored in a list) to be used by the last 50.
I thought that if I pass the Runnable
s in the executor.execute()
in the order they are in the list, they would bealso executed in the same order.
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?
谢谢
推荐答案
您需要分两批提交作业,或者以其他方式创建显式的先于先后"关系.建议构建两批作业并使用invokeAll(batch1); invokeAll(batch2);
.invokeAll()
方法将执行所有任务并阻塞直到完成.您可能需要将Runnable
包装为Callable
,可以使用Executors.callable(Runnable r)
进行包装. (@Cameron Skinner击败了我,得到了一些代码示例,有关更多信息,请参见该答案.)
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);
The invokeAll()
method will execute all of the tasks and block until they complete. You may need to wrap your Runnable
s as Callable
s, which you can do with Executors.callable(Runnable r)
. (@Cameron Skinner beat me to getting some code example, see that answer for more...)
执行者的全部要点是抽象出执行的细节,因此除非明确说明,否则不能保证顺序.如果要严格顺序执行,请在运行的线程中(最简单)执行,或者在单线程执行程序ala Executors.newSingleThreadExecutor()
中执行,或显式同步任务.如果要执行后者,则可以使用屏障或闩锁,并在屏障/闩锁上放置相关任务.您还可以让第一个任务块实现Callable
,返回Future
,并让相关任务调用myFuture.get()
,这将导致它们阻塞直到返回结果.
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. 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.
如果您对特定的应用程序有更多的了解,我们也许可以提供更具体的帮助.
If you say more about your specific application, we might be able to help more specifically.
这篇关于ThreadPool不会按顺序运行任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!