我正在使用固定大小的Java线程池(ExecutorService) . 假设我向线程池提交作业,作业空闲 .
是否有可能从线程池中删除空闲作业,以便可以处理队列中的其他作业,然后再次添加空闲作业?
如果从 ExecutorService 移至ThreadPoolExecutor,则可以使用以下API实现
ExecutorService
public void setCorePoolSize(int corePoolSize)
设置核心线程数 . 这将覆盖构造函数中设置的任何值 . 如果新值小于当前值,则当下一个空闲时,多余的现有线程将被终止 . 如果需要更大,则新线程将启动以执行任何排队任务 .
如果要在运行时重新调整池的大小,
((ThreadPoolExecutor)service).setCorePoolSize(newLimit); // newLimit是池的新大小
((ThreadPoolExecutor)service).setCorePoolSize(newLimit);
其他API:
public void setMaximumPoolSize(int maximumPoolSize)
设置允许的最大线程数 . 这将覆盖构造函数中设置的任何值 . 如果新值小于当前值,则当下一个空闲时,多余的现有线程将被终止 .
任务或 Runnable 可能在 idle (我想等待I / O或其他资源)的事实是主要原因之一,因为适合使用线程池 .
Runnable
idle
另一方面,您希望使用的线程数量是您需要调整的,以便在某些线程被阻塞等待资源时允许处理任务 .
您需要做的唯一考虑是观察线程进入空闲状态的频率并相应地调整线程数量 .
不要对同步等待其他任务结果的任务进行排队 . 这可能导致上述形式的死锁,其中所有线程都被任务占用,而这些任务又等待由于所有线程都忙而无法执行的排队任务的结果 . 使用池化线程进行潜在的长期操作时要小心 . 如果程序必须等待资源(例如I / O完成),请指定最长等待时间,然后将该任务失败或重新排队以便稍后执行 . 这可以保证最终通过为可能成功完成的任务释放线程来取得一些进展 . 了解你的任务 . 要有效地调整线程池大小,您需要了解正在排队的任务以及它们正在执行的操作 . 它们受CPU限制吗?它们是I / O绑定的吗?您的答案将影响您调整应用程序的方式 . 如果您有不同类别的任务具有完全不同的特征,那么为不同类型的任务提供多个工作队列可能是有意义的,因此可以相应地调整每个池 .
2 回答
如果从
ExecutorService
移至ThreadPoolExecutor,则可以使用以下API实现如果要在运行时重新调整池的大小,
((ThreadPoolExecutor)service).setCorePoolSize(newLimit);
// newLimit是池的新大小其他API:
任务或
Runnable
可能在idle
(我想等待I / O或其他资源)的事实是主要原因之一,因为适合使用线程池 .另一方面,您希望使用的线程数量是您需要调整的,以便在某些线程被阻塞等待资源时允许处理任务 .
您需要做的唯一考虑是观察线程进入空闲状态的频率并相应地调整线程数量 .
调整ThreadPool的指南(来自:IBM ThreadPools和Work Queue)