为什么 ScheduledThreadPoolExecutor 只接受固定数量的线程?

发布于 2024-09-11 23:34:57 字数 120 浏览 3 评论 0原文

我可能会想象一些任务计划花费很长时间,并且 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

姐不稀罕 2024-09-18 23:34:57

至于为什么,我也不知道。但我可以想象。

计算机的资源量是有限的。并非所有资源都可以同时处理。

如果多个进程同时加载文件,它们的加载速度将比顺序加载慢(至少在硬盘上)。

处理器对并发处理多个线程的支持也很有限。在某些时候,操作系统或 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 ScheduledThreadPoolExecutors, one for IO bound tasks and one for CPU bound tasks.

蓝天白云 2024-09-18 23:34:57

在进一步挖掘 SchecduledThreadPoolExecutor 时,我发现了这个 链接< /a>,这个链接解释了SchecduledThreadPoolExecutor解决了Timer类的许多问题。引入SchecduledThreadPoolExecutor的原因也是为了取代Timer(由于Timer的各种问题)。
我认为将固定数量的线程传递给 SchecduledThreadPoolExecutor 的原因是此类解决的问题之一。 IE

Timer类只启动一个
线。虽然效率更高
不是为每个任务创建一个线程,而是
不是最佳解决方案。最优的
解决方案可能是使用一些
一个线程之间的所有线程
任务和每个任务一个线程。在
效果,最好的解决方案是放置
线程池中的任务。这
池中的线程数应该
在施工期间可分配给
让程序确定
池中的最佳线程数。

所以在我看来,这就是 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.

The Timer class starts only one
thread. While it is more efficient
than creating a thread per task, it is
not an optimal solution. The optimal
solution may be to use a number of
threads between one thread for all
tasks and one thread per task. In
effect, the best solution is to place
the tasks in a pool of threads. The
number of threads in the pool should
be assignable during construction to
allow the program to determine the
optimal number of threads in the pool.

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 :)

染年凉城似染瑾 2024-09-18 23:34:57

根据 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文