简体   繁体   English

从Java中的线程池中删除空闲线程?

[英]Removing idle threads from thread pool in Java?

I'm using a Java thread pool of fixed size (ExecutorService). 我正在使用固定大小(ExecutorService)的Java线程池。 Let's assume that I submit a job to the thread pool and the job gets idle. 假设我将作业提交到线程池中,并且该作业变得空闲。

Is there a possibility that idle jobs are removed from the thread pool, so that other jobs from the queue can be processed and then the idle job is later added again? 是否有可能从线程池中删除空闲作业,以便可以处理队列中的其他作业,然后稍后再次添加空闲作业?

The fact that a task or a Runnable may be in idle (I suppose waiting for I/O or some other resource) is one of the main reason because is appropriate to use a thread pool. 该任务或事实上Runnable可在idle (我想等待I / O或某些其它资源)是最主要的原因,因为是适合使用线程池一个。

The amount of thread that you want to use on the other hand, is what you need to tune, in order to allow the task to be processed when some of the thread is blocked waiting for a resource. 另一方面,要使用的线程数量就是需要调整的数量,以便在某些线程被阻塞等待资源时允许处理任务。

The only think you need to do is observe how often the thread are getting into idle and tune the amount of thread accordingly. 您唯一需要做的就是观察线程进入空闲状态的频率,并相应地调整线程数量。

Guideline to tune a ThreadPool (from: IBM ThreadPools and Work Queue ) 调整ThreadPool的准则(来自: IBM ThreadPools和Work Queue

Don't queue tasks that wait synchronously for results from other tasks. 不要将同步等待其他任务结果的任务排队。 This can cause a deadlock of the form described above, where all the threads are occupied with tasks that are in turn waiting for results from queued tasks that can't execute because all the threads are busy. 这可能会导致上述形式的死锁,在该死锁中,所有线程都被任务占用,而这些任务又轮流等待由于所有线程都忙而无法执行的排队任务的结果。

Be careful when using pooled threads for potentially long-lived operations. 在将池化线程用于可能长期运行的操作时要小心。 If the program must wait for a resource, such as an I/O completion, specify a maximum wait time, and then fail or requeue the task for execution at a later time. 如果程序必须等待资源(例如I / O完成),请指定最大等待时间,然后使任务失败或重新排队以供以后执行。 This guarantees that eventually some progress will be made by freeing the thread for a task that might complete successfully. 这保证了通过释放线程执行可能成功完成的任务最终将取得一些进展。

Understand your tasks. 了解您的任务。 To tune the thread pool size effectively, you need to understand the tasks that are being queued and what they are doing. 为了有效地调整线程池的大小,您需要了解正在排队的任务以及它们在做什么。 Are they CPU-bound? 它们是否受CPU限制? Are they I/O-bound? 它们是否受I / O约束? Your answers will affect how you tune your application. 您的答案将影响您调整应用程序的方式。 If you have different classes of tasks with radically different characteristics, it may make sense to have multiple work queues for different types of tasks, so each pool can be tuned accordingly. 如果您具有特性完全不同的不同类别的任务,则可以为不同类型的任务设置多个工作队列,因此可以相应地调整每个池。

If you move from ExecutorService to ThreadPoolExecutor , you can achieve it with below API 如果从ExecutorService转到ThreadPoolExecutor ,则可以使用以下API来实现

public void setCorePoolSize(int corePoolSize)

Sets the core number of threads. 设置核心线程数。 This overrides any value set in the constructor. 这将覆盖构造函数中设置的任何值。 If the new value is smaller than the current value, excess existing threads will be terminated when they next become idle. 如果新值小于当前值,则多余的现有线程将在下次空闲时终止。

If larger, new threads will, if needed, be started to execute any queued tasks. 如果更大,将在需要时启动新线程以执行任何排队的任务。

If you want to re-size the pool at run time, 如果您想在运行时调整池的大小,

((ThreadPoolExecutor)service).setCorePoolSize(newLimit); //newLimit is new size of the pool // newLimit是池的新大小

Other API: 其他API:

public void setMaximumPoolSize(int maximumPoolSize)

Sets the maximum allowed number of threads. 设置允许的最大线程数。 This overrides any value set in the constructor. 这将覆盖构造函数中设置的任何值。 If the new value is smaller than the current value, excess existing threads will be terminated when they next become idle. 如果新值小于当前值,则多余的现有线程将在下次空闲时终止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM