面试题答案
一键面试关键指标
- 活跃线程数:表示当前正在执行任务的线程数量。通过监控活跃线程数,可以了解线程池的繁忙程度。如果活跃线程数持续接近或达到线程池的最大线程数,可能意味着系统负载过高,需要考虑增加线程池容量或优化任务处理逻辑。
- 任务队列大小:线程池中的任务队列用于存放等待执行的任务。监控任务队列大小有助于了解任务的堆积情况。如果任务队列持续增长且不被消费,可能导致内存溢出等问题,也表明线程池处理能力不足。
- 已完成任务数:统计线程池已经成功执行完成的任务数量。这个指标可以反映线程池的整体工作效率,结合时间维度分析已完成任务数,能评估系统在不同时间段的处理能力。
- 线程池状态:线程池有不同的状态,如RUNNING、SHUTDOWN、STOP、TERMINATED等。监控线程池状态可以及时发现线程池是否正常运行,例如是否意外进入SHUTDOWN状态导致新任务无法提交。
- 拒绝任务数:当线程池和任务队列都已满,新提交的任务会被拒绝。监控拒绝任务数,可以判断系统是否出现过载情况,需要及时调整线程池参数或优化业务逻辑以避免任务丢失。
代码实现动态监控
- 使用类库:可以使用Java自带的
java.util.concurrent
包下的相关类,如ThreadPoolExecutor
。该类提供了获取上述关键指标的方法。 - 关键方法:
- 获取活跃线程数:
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);