BlogBlog
首页
  • Vue
  • TypeScript
  • React
  • Angular
  • Node.js
  • 小程序
  • Flutter
  • 数据产品
  • 大数据

    • Hadoop
    • Hive
    • Spark
  • MySQL
  • Redis
  • Java
  • Python
  • Golang
GitHub
首页
  • Vue
  • TypeScript
  • React
  • Angular
  • Node.js
  • 小程序
  • Flutter
  • 数据产品
  • 大数据

    • Hadoop
    • Hive
    • Spark
  • MySQL
  • Redis
  • Java
  • Python
  • Golang
GitHub

线程池监控

监控指标

  • 线程池状态: 线程池是否关闭,是否终止
  • 线程池大小: 核心线程数,最大线程数,当前活跃线程数
  • 任务队列: 队列的大小,队列的类型, 允许的数量,已存放的数量
  • 任务执行统计: 已完成的任务数,已拒绝的任务数,正在执行的任务数
  • 线程池当前负载: 当前线程数 / 最大线程数
  • 线程池峰值负载:当前线程数 / 最大线程数,线程池运行期间最大的负载

对应的方法

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();  
    }  
}

最近更新:: 2025/5/5 12:43
Contributors: alice