当试图确定如何在Java的数据处理服务器中分解这些任务时,我需要知道对于ExecutorService来说有多少个期货是太多的。
据我所知,具有重量级线程池的ExecutorServices处理期货就像处理绿色线程一样,这意味着执行“期货”之间上下文切换的成本非常小。这是真的吗?
我是否应该向ExecutorService提交数百万份期货(使用池中固定数量的线程)?
我能否期望将许多非常短命的期货(10毫秒)提交到执行者服务中,而不会出现严重的性能下降?
发布于 2020-09-17 15:40:40
您将表示异步操作的可能结果的Future与表示在Callable上执行处理能力的Thread (至少在Executor的情况下)混为一谈。
没有什么可以阻止您在线程池上调用submit数百万次,并获得一个巨大的Future对象列表供您等待。如果应用程序将继续运行,并且不需要处理结果,甚至不需要等待它们完成。
但。
如果您创建了所有这些作业,它们将需要内存来保存它们的状态。如果该内存在某种程度上是作业输入的一部分,或者是执行作业的结果,那么您将向所有这些任务提交堆空间。你不能永远这样做。本质上,如果要将大量的工作拖到进程中以在后台运行,则需要考虑某种节流。
发布于 2020-09-17 16:11:22
据我所知,拥有重量级线程池的
处理期货就像处理绿色线程一样
这不对。如果忽略这些提示,ExecutorService由工作线程的集合和任务的阻塞队列组成。队列中的每个任务都是一个包装器,包含一个任务和一个Future。
每个工作线程都会永远循环,
Runnable或Callable对象的run()或call(...)方法,H 112使用方法返回的值来完成Future,或者,除了您的方法引发的异常之外,<
H 115返回到另一个任务。H 216F 217唯一的线程是“重量级”工作线程。一旦其中一个工作线程开始处理某个任务,在任务完成之前,它将不会执行任何其他操作。尚未启动的任务只是队列中的对象,执行程序在未来完成后就会忘记每个任务和未来对象。在您自己的代码放弃了对它们的引用之后,这些代码就不会继续存在。
发布于 2020-09-17 17:09:23
我应该向ExecutorService提交数百万份期货吗?
你可以,但你应该评估可能的时间开销。处理单独的未来对象的开销很小,但大于零。所以任务越少越好。另一方面,当任务数小于处理器数(即与超线程相关的处理器核数)时,并行性水平就会降低,总的执行时间也会增加。
让你有一百万的10毫秒任务,你的电脑有8个核心.这样,1250秒的总执行时间就会增加(10*8/2) = 40 ms,这是因为在结束时减少了并行性,而对于任务切换则增加了125 ms (我估计每个任务开关只有1 useq )。如果你有100000个100毫秒的任务,那么执行时间仍然是1250秒,加上400毫秒的尾巴和12.5毫秒的开关。无论哪种方式,时间开销都是可以忽略的,但是如果任务明显短于或超过10.100间隔,则时间开销会增加。
https://stackoverflow.com/questions/63941131
复制相似问题