ThreadPool不按顺序运行任务
我正在使用 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 be
also 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?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要分两批提交作业,或者以其他方式创建显式的“发生之前”关系。建议构建两批作业并使用
invokeAll(batch1); invokeAll(batch2);
invokeAll()
方法将执行所有任务并阻塞,直到它们完成。您可能需要将 Runnable 包装为 Callable,可以使用 Executors.callable(Runnable r) 来实现。 (@Cameron Skinner 让我获得了一些代码示例,请参阅该答案以获取更多信息...)执行器的全部要点是抽象出执行的细节,因此除非明确说明,否则不能保证顺序。如果您想要严格顺序执行,请在您正在运行的线程中执行(最简单),在单线程执行器中执行,ala
Executors.newSingleThreadExecutor()
,或显式同步任务。如果您想执行后者,您可以使用屏障或锁存器,并将相关任务块放在屏障/锁存器上。您还可以让第一个任务块实现 Callable,返回 Future,并让依赖任务调用 myFuture.get(),这会导致他们阻塞直到结果返回。如果您详细说明您的具体应用,我们也许能够提供更具体的帮助。
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);
TheinvokeAll()
method will execute all of the tasks and block until they complete. You may need to wrap yourRunnable
s asCallable
s, which you can do withExecutors.callable(Runnable r)
. (@Cameron Skinner beat me to getting some code example, see that answer for more...)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 implementCallable
, returnFuture
, and have the dependent tasks callmyFuture.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.
这是正确的行为。您无法保证 Runnable 的执行顺序。
执行器以并行方式运行,而您似乎希望任务以串行方式运行。您可以提交前 50 个作业,等待它们完成,然后提交后 50 个作业,或者(如果执行顺序很重要)仅在单个线程中运行它们。
例如,
That is the correct behaviour. You have no guarantees about which order the Runnables are executed.
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.
For example,
也许您可以
执行
前 50 个、shutdown
和awaitTermination
,然后才执行
其他 50 个?有关一些示例代码,请参阅此答案。Perhaps you could
execute
the first 50,shutdown
andawaitTermination
, and only thenexecute
the other 50? See this answer for some sample code.