为什么 ScheduledThreadPoolExecutor 只接受固定数量的线程?
我可能会想象一些任务计划花费很长时间,并且 ScheduledThreadPoolExecutor 将为需要运行的其他任务创建额外的线程,直到达到最大线程数。
但似乎我只能为池指定固定数量的线程,为什么会这样?
I may imagine some tasks scheduled to take a very long time and ScheduledThreadPoolExecutor
would create additional threads for the other tasks that need to be run, until a maximum number of threads is reached.
But seems that I can only specify a fixed number of threads for the pool, why is that so ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
至于为什么,我也不知道。但我可以想象。
计算机的资源量是有限的。并非所有资源都可以同时处理。
如果多个进程同时加载文件,它们的加载速度将比顺序加载慢(至少在硬盘上)。
处理器对并发处理多个线程的支持也很有限。在某些时候,操作系统或 JVM 将花费更多的时间来切换线程,而不是线程执行其代码所花费的时间。
这是
ScheduledThreadPoolExecutor
如此设计的一个很好的理由。您可以将任意数量的作业放入队列中,但同时执行的作业数量永远不会超过有效运行的作业数量。当然,这取决于你来平衡。如果您的任务受 IO 限制,我会将池大小设置得较小,如果它们受 CPU 限制,则设置得大一些(32 左右)。您还可以创建多个
ScheduledThreadPoolExecutor
,一个用于 IO 密集型任务,另一个用于 CPU 密集型任务。As the why, I don't know either. But I can imagine.
The amount of resources of a computer is limited. Not all resources can be handled concurrently either.
If multiple processes concurrently load files, they will be loaded slower than if they were being loaded sequentially (at least on a harddisk).
A processor also has limited support for handling multiple threads concurrently. At some point the OS or JVM will spend more time switching threads, than threads spend executing their code.
That is a good reason for the
ScheduledThreadPoolExecutor
to be designed the way it is. You can put any amount of jobs on the queue, but there are never executed more jobs at the same time than can be run efficiently. It's up to you to balance that, of course.If your tasks are IO bound, I'd set the pool size small, and if they are CPU bound, a bit larger (32 or so). You can also make multiple
ScheduledThreadPoolExecutor
s, one for IO bound tasks and one for CPU bound tasks.在进一步挖掘 SchecduledThreadPoolExecutor 时,我发现了这个 链接< /a>,这个链接解释了SchecduledThreadPoolExecutor解决了Timer类的许多问题。引入SchecduledThreadPoolExecutor的原因也是为了取代Timer(由于Timer的各种问题)。
我认为将固定数量的线程传递给 SchecduledThreadPoolExecutor 的原因是此类解决的问题之一。 IE
所以在我看来,这就是 SchecduledThreadPoolExecutor 用例的来源。对于您的情况,您应该能够根据您计划安排的任务以及完成这些任务所需的时间来确定最佳值。如果我有 4 个长时间运行的任务安排在同一时间,如果同时还有其他任务要执行,我希望我的池大小大于 4。我还希望将长时间运行的任务分开在不同的执行器中,如前面的答案所示。
希望这有帮助:)
While digging further about SchecduledThreadPoolExecutor I found this link, This link explains SchecduledThreadPoolExecutor solves many problems of Timer class. And also reason for introducing SchecduledThreadPoolExecutor was to replace Timer (due to various problems with Timer).
I think Reason for fixed number of threads passed to SchecduledThreadPoolExecutor is in one of problems this class solves. i.e.
So in my opinion this is where use case for SchecduledThreadPoolExecutor is coming from. In your case, You should be able to decide optimal value depending upon tasks you plan to schedule and time these tasks takes to finish. If I have 4 long running tasks which are scheduled for same time I would prefer my pool size be greater than 4 if there are other tasks to be executed during same time. I would also prefer to seperate out long running tasks in different executor as indicated in earlier answers.
Hope this helps :)
根据 Java 并发实践,无限线程创建有以下缺点:
线程生命周期开销< /strong>
线程的创建和拆除不是免费的。线程创建需要时间,并且需要 JVM 和操作系统进行一些处理活动。
资源消耗
活动线程会消耗系统资源,尤其是内存。当可运行线程多于可用处理器时,线程将处于空闲状态。拥有许多空闲线程会占用大量内存,给垃圾收集器带来压力,并且拥有许多线程竞争 CPU 还会带来其他性能成本。如果您有足够的线程来保持所有 CPU 忙碌,那么创建更多线程不会有任何帮助,甚至可能会造成伤害。
稳定性
可以创建的线程数量是有限制的。该限制因平台而异,并受到 JVM 调用参数、Thread 构造函数中请求的堆栈大小以及底层操作系统对线程的限制等因素的影响。当您达到此限制时,最可能的结果是 OutOfMemoryError。尝试从此类错误中恢复是非常危险的;构建程序以避免达到此限制要容易得多。
在某一点上,更多的线程可以提高吞吐量,但超过这一点,创建更多的线程只会减慢应用程序的速度,并且创建过多的线程可能会导致整个应用程序严重崩溃。避免危险的方法是对应用程序创建的线程数设置一些限制,并彻底测试应用程序以确保即使达到此限制,它也不会耗尽资源。
在原型设计和开发过程中,无限制的线程创建可能看起来工作得很好,只有在部署应用程序并且负载很重时才会出现问题。
According to Java Concurrency In Practice there are the following disadvantages of unbounded thread creation:
Thread lifecyle overhead
Thread creation and teardown are not free. Thread creation takes time, and requires some processing activity by the JVM and OS.
Resource consumption
Active threads consume system resources, especially memory. When there are more runnable threads than available processors, threads sit idle. Having many idle threads can tie up a lot of memory, putting pressure on the garbage collector, and having many threads competing for the CPUs can impose other performance costs as well. If you have enough threads to keep all the CPUs busy, creating more threads won't help and may even hurt.
Stability
There is a limit on how many threads can be created. The limit varies by platform and is affected by factors including JVM invocation parameters, the requested stack size in the Thread constructor, and limits on threads placed by the underlying operating system. When you hit htis limit, the most likely result is an OutOfMemoryError. Trying to recover from such an error is very risky; it is far easier to structur your program to avoid hitting this limit.
Up to a certain point, more threads can improve throughput, but beyond that point creating more threads just slows down your application, and creating one thread too many can cause your entire application to crash horribly. The way to stay out of danger is to place some bound on how many threads your application creates, and to test your application thoroughly to ensure that, even when this bound is reached, it does not run out of resources.
Unbounded thread creation may appear to work just fine during prototyping and development, with problems surfacing only when the application is deployed and under heavy load.