ThreadPoolExecutor参数 keepAliveTime allowCoreThreadTimeOut
创始人
2024-05-29 00:24:02
0

/*** Timeout in nanoseconds for idle threads waiting for work.* Threads use this timeout when there are more than corePoolSize* present or if allowCoreThreadTimeOut. Otherwise they wait* forever for new work.*/
private volatile long keepAliveTime;

等待工作的空闲线程的超时(以纳秒为单位)。
当存在超过 corePoolSize(即非核心线程) 或 allowCoreThreadTimeOut 为 true 时,线程使用此参数作为定时。
否则,他们会永远等待新的工作。

/*** If false (default), core threads stay alive even when idle.* If true, core threads use keepAliveTime to time out waiting* for work.*/
private volatile boolean allowCoreThreadTimeOut;

如果为 false(默认值),则核心线程即使在空闲时也保持活动状态。
如果为 true,核心线程使用 keepAliveTime 定时等待工作。

/*** Sets the policy governing whether core threads may time out and* terminate if no tasks arrive within the keep-alive time, being* replaced if needed when new tasks arrive. When false, core* threads are never terminated due to lack of incoming* tasks. When true, the same keep-alive policy applying to* non-core threads applies also to core threads. To avoid* continual thread replacement, the keep-alive time must be* greater than zero when setting {@code true}. This method* should in general be called before the pool is actively used.** @param value {@code true} if should time out, else {@code false}* @throws IllegalArgumentException if value is {@code true}*         and the current keep-alive time is not greater than zero** @since 1.6*/
public void allowCoreThreadTimeOut(boolean value) {if (value && keepAliveTime <= 0)throw new IllegalArgumentException("Core threads must have nonzero keep alive times");if (value != allowCoreThreadTimeOut) {allowCoreThreadTimeOut = value;if (value)interruptIdleWorkers();}
}

从注释得知
当设置为 false,核心线程在缺少任务执行的情况下也不终止。
当设置为 true,核心线程的存活策略适用于非核心线程。
防止线程持续替换,当设置 allowCoreThreadTimeOut 为 true 时 keepAliveTime 必须大于0.
传入的参数值与 allowCoreThreadTimeOut 的默认值不同时,先将 allowCoreThreadTimeOut 进行赋值为 true(默认值为 false),再终止线程。

keepAliveTime设置成多少比较合适

从如下链接得知

https://www.zhihu.com/question/322212282/answer/667964027

1、keepAliveTime的存在的意义在于可以减少过于频繁的线程启动停止带来的性能消耗。

2、keepAliveTime的建议值在任何书籍、文档中都没有提到过。如果真的有建议值的话,我相信JDK会封装常量类。

3、keepAliveTime的值要视具体业务场景对待,如果这个线程池用在主业务逻辑上我觉得这个值设置为0也OK,如果这个线程池用在一个服务中且这个服务是单独一台机器部署的我觉得设置0也任然OK,如果这个线程池要执行的任务是非常密集型的我觉得这是0也同样OK。业务类型、业务权重、实施部署条件以及没一个具体的线程大概执行时间等都要考虑。

4、我见到过keepAliveTime设置为0,在线程体中根据条件来休眠线程的,我觉得这种方式也不错

这个看应用场景的,JDK自带的两种线程池构造:

newFixedThreadPool-0ms,固定大小的永不过期

newCachedThreadPool-60s,缓存大小的60秒过期

核心线程和非核心都用到这个变量值。设置回收核心线程时,这个值需要大于0。

考虑到实际情况,如果是普通任务后台执行时间很长的话,可以设置时长为1小时,1小时的时间是我接触过的很长的任务了,我做的一个项目通过定时任务后台执行就用了起码10分钟以上,好处是这个对时间要求不敏感,是夜里执行的任务。普通的web请求的话设置为1分钟即可。这样可以照顾到核心线程回收 keepAliveTime 设置的值需要大于0 的问题。

核心线程收回

设置 allowCoreThreadTimeOut 为 true ,keepAliveTime 设置的值需要大于0。

活跃执行任务的线程大致总数

/*** Returns the approximate number of threads that are actively* executing tasks.** @return the number of threads*/
public int getActiveCount() {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {int n = 0;for (Worker w : workers)if (w.isLocked())++n;return n;} finally {mainLock.unlock();}
}

已经调度执行的任务大致总数

/*** Returns the approximate total number of tasks that have ever been* scheduled for execution. Because the states of tasks and* threads may change dynamically during computation, the returned* value is only an approximation.** @return the number of tasks*/
public long getTaskCount() {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {long n = completedTaskCount;for (Worker w : workers) {n += w.completedTasks;if (w.isLocked())++n;}return n + workQueue.size();} finally {mainLock.unlock();}
}

已经完成的任务总数

/*** Returns the approximate total number of tasks that have* completed execution. Because the states of tasks and threads* may change dynamically during computation, the returned value* is only an approximation, but one that does not ever decrease* across successive calls.** @return the number of tasks*/
public long getCompletedTaskCount() {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {long n = completedTaskCount;for (Worker w : workers)n += w.completedTasks;return n;} finally {mainLock.unlock();}
}

发现用到了全局变量 completedTaskCount

/*** Counter for completed tasks. Updated only on termination of* worker threads. Accessed only under mainLock.*/
private long completedTaskCount;

由注释得知,是历史任务结束后的数量统计。

可以得知,想要知道当前任务有多少线程在执行,通过 getActiveCount() 可以得到。

获取任务队列大小

/*** Returns the task queue used by this executor. Access to the* task queue is intended primarily for debugging and monitoring.* This queue may be in active use.  Retrieving the task queue* does not prevent queued tasks from executing.** @return the task queue*/
public BlockingQueue getQueue() {return workQueue;
}

返回线程池中线程数量

/*** Returns the current number of threads in the pool.** @return the number of threads*/
public int getPoolSize() {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {// Remove rare and surprising possibility of// isTerminated() && getPoolSize() > 0return runStateAtLeast(ctl.get(), TIDYING) ? 0: workers.size();} finally {mainLock.unlock();}
}

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...