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

时间:2016-04-19 23:54:45

标签: java multithreading threadpool executorservice

我正在使用固定大小的Java线程池(ExecutorService)。假设我向线程池提交了一个作业,并且作业空闲。

是否有可能从线程池中删除空闲作业,以便可以处理队列中的其他作业,然后再次添加空闲作业?

2 个答案:

答案 0 :(得分:3)

任务或Runnable可能在idle(我想等待I / O或其他资源)的事实是主要原因之一,因为适合使用线程池

另一方面,您想要使用的线程数量是您需要调整的,以便在某些线程被阻塞等待资源时允许处理任务。

您唯一需要做的就是观察线程进入空闲状态的频率并相应地调整线程数量。

调整ThreadPool的指南(来自:IBM ThreadPools and Work Queue

  

不要对同步等待其他任务结果的任务进行排队。这可能导致上述形式的死锁,其中所有线程都被任务占用,而这些任务又等待排队任务的结果,这些任务由于所有线程都忙而无法执行。

     

使用池化线程进行潜在的长期操作时要小心。如果程序必须等待资源(例如I / O完成),请指定最长等待时间,然后将该任务失败或重新排队以便稍后执行。这可以保证最终通过释放可能成功完成的任务的线程来取得一些进展。

     

了解您的任务。要有效地调整线程池大小,您需要了解正在排队的任务以及它们正在执行的操作。它们受CPU限制吗?它们是I / O绑定的吗?您的答案将影响您调整应用程序的方式。如果您有不同类别的任务具有完全不同的特征,那么为不同类型的任务设置多个工作队列可能是有意义的,因此可以相应地调整每个池。

答案 1 :(得分:3)

如果您从ExecutorService移至ThreadPoolExecutor,则可以使用以下API实现

public void setCorePoolSize(int corePoolSize)
  

设置核心线程数。这将覆盖构造函数中设置的任何值。如果新值小于当前值,则当下一个空闲时,多余的现有线程将被终止。

     

如果更大,如果需要,将启动新线程以执行任何排队任务。

如果要在运行时重新调整池的大小,

((ThreadPoolExecutor)service).setCorePoolSize(newLimit); // newLimit是池的新大小

其他API:

public void setMaximumPoolSize(int maximumPoolSize)
  

设置允许的最大线程数。这将覆盖构造函数中设置的任何值。如果新值小于当前值,则过多的现有线程将在下一次空闲时终止。