MST

星途 面试题库

面试题:Java线程池异常监控的关键指标有哪些及如何通过代码实现监控

阐述在对Java线程池异常进行监控时,需要重点关注的关键指标,如线程池活跃线程数、任务队列大小等。并说明如何通过代码来实现对这些关键指标的动态监控,包括使用哪些类库和关键方法。
26.3万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

关键指标

  1. 活跃线程数:表示当前正在执行任务的线程数量。通过监控活跃线程数,可以了解线程池的繁忙程度。如果活跃线程数持续接近或达到线程池的最大线程数,可能意味着系统负载过高,需要考虑增加线程池容量或优化任务处理逻辑。
  2. 任务队列大小:线程池中的任务队列用于存放等待执行的任务。监控任务队列大小有助于了解任务的堆积情况。如果任务队列持续增长且不被消费,可能导致内存溢出等问题,也表明线程池处理能力不足。
  3. 已完成任务数:统计线程池已经成功执行完成的任务数量。这个指标可以反映线程池的整体工作效率,结合时间维度分析已完成任务数,能评估系统在不同时间段的处理能力。
  4. 线程池状态:线程池有不同的状态,如RUNNING、SHUTDOWN、STOP、TERMINATED等。监控线程池状态可以及时发现线程池是否正常运行,例如是否意外进入SHUTDOWN状态导致新任务无法提交。
  5. 拒绝任务数:当线程池和任务队列都已满,新提交的任务会被拒绝。监控拒绝任务数,可以判断系统是否出现过载情况,需要及时调整线程池参数或优化业务逻辑以避免任务丢失。

代码实现动态监控

  1. 使用类库:可以使用Java自带的java.util.concurrent包下的相关类,如ThreadPoolExecutor。该类提供了获取上述关键指标的方法。
  2. 关键方法
    • 获取活跃线程数
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
int activeCount = executor.getActiveCount();
- **获取任务队列大小**:
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
int queueSize = executor.getQueue().size();
- **获取已完成任务数**:
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
long completedTaskCount = executor.getCompletedTaskCount();
- **获取线程池状态**:
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
ThreadPoolExecutor.State state = executor.getState();
- **获取拒绝任务数**:可以通过自定义拒绝策略来统计拒绝任务数。例如:
class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
    private AtomicInteger rejectedCount = new AtomicInteger();
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        rejectedCount.incrementAndGet();
        // 可以在这里添加自定义的处理逻辑,比如记录日志等
    }
    public int getRejectedCount() {
        return rejectedCount.get();
    }
}
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new CustomRejectedExecutionHandler());
CustomRejectedExecutionHandler handler = (CustomRejectedExecutionHandler)executor.getRejectedExecutionHandler();
int rejectedCount = handler.getRejectedCount();

为了实现动态监控,可以在一个定时任务(如ScheduledExecutorService)中定期获取这些指标并进行记录或分析:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(() -> {
    int activeCount = executor.getActiveCount();
    int queueSize = executor.getQueue().size();
    long completedTaskCount = executor.getCompletedTaskCount();
    ThreadPoolExecutor.State state = executor.getState();
    CustomRejectedExecutionHandler handler = (CustomRejectedExecutionHandler)executor.getRejectedExecutionHandler();
    int rejectedCount = handler.getRejectedCount();
    // 这里可以将获取到的指标数据进行记录,如写入日志或发送到监控系统
}, 0, 1, TimeUnit.SECONDS);