线程池监控
监控指标
- 线程池状态: 线程池是否关闭,是否终止
- 线程池大小: 核心线程数,最大线程数,当前活跃线程数
- 任务队列: 队列的大小,队列的类型, 允许的数量,已存放的数量
- 任务执行统计: 已完成的任务数,已拒绝的任务数,正在执行的任务数
- 线程池当前负载: 当前线程数 / 最大线程数
- 线程池峰值负载:当前线程数 / 最大线程数,线程池运行期间最大的负载
对应的方法
ThreadPoolExecutor 提供了一下方法获取线程池的指标
- getCorePoolSize(): 核心线程数
- getMaximumPoolSize(): 最大线程数
- getQueue(): 获取线程池中的阻塞队列,并通过阻塞队列中的方法获取队列长度、元素个数等。
- getPoolSize():获取线程池中的工作线程数(包括核心线程和非核心线程)。
- getActiveCount():获取活跃线程数,也就是正在执行任务的线程。
- getLargestPoolSize():获取线程池曾经到过的最大工作线程数。
- getTaskCount():获取历史已完成以及正在执行的总的任务数量。
除此之外,ThreadPoolExecutor中还提供了一些未实现的钩子方法,我们可以通过重写这些方法来实现更多指标数据的获取。
- beforeExecute,在Worker线程执行任务之前会调用的方法。
- afterExecute,在Worker线程执行任务之后会调用的方法。
- terminated,当线程池从状态变更到TERMINATED状态之前调用的方法。
比如我们可以在beforeExecute方法中记录当前任务开始执行的时间,再到afterExecute方法来计算任务执行的耗时、最大耗时、最小耗时、平均耗时等。
简单的实现线程池监控
import java.util.concurrent.ThreadPoolExecutor;
public class MonitoredThreadPoolExecutor extends ThreadPoolExecutor{
public MonitoredThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, java.util.concurrent.TimeUnit unit,
java.util.concurrent.BlockingQueue<Runnable> workQueue){
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
// 获取当前线程池状态信息
public String getStatusInfo() {
StringBuilder sb = new StringBuilder();
sb.append("ThreadPool Status: ").append(isShutdown() ? "SHUTDOWN" : "RUNNING").append("\n");
sb.append(" Core Pool Size: ").append(getCorePoolSize()).append("\n");
sb.append(" Max Pool Size: ").append(getMaximumPoolSize()).append("\n");
sb.append(" Active Threads: ").append(getActiveCount()).append("\n");
sb.append(" Task Queue Size: ").append(getQueue().size()).append("\n");
sb.append(" Completed Tasks: ").append(getCompletedTaskCount()).append("\n");
sb.append(" Rejected Tasks: ").append(getRejectedExecutionCount()).append("\n");
return sb.toString();
}
}
import java.util.concurrent.LinkedBlockingQueue;
public class ThreadPoolMonitorExample {
public static void main(String[] args) {
// 创建一个线程池,使用MonitoredThreadPoolExecutor
MonitoredThreadPoolExecutor executor = new MonitoredThreadPoolExecutor(
5, 10, 60L, java.util.concurrent.TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>());
// 提交任务到线程池...
// executor.execute(...);
// 在需要的时候获取线程池状态信息
System.out.println(executor.getStatusInfo());
// 关闭线程池(通常在应用程序关闭时)
// executor.shutdown();
}
}