java线程池的监控_Java并发(六)线程池监控

importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importjava.util.Date;importjava.util.List;importjava.util.Objects;import java.util.concurrent.*;importjava.util.concurrent.atomic.AtomicInteger;/*** 继承ThreadPoolExecutor类,覆盖了shutdown(), shutdownNow(), beforeExecute() 和 afterExecute()

* 方法来统计线程池的执行情况

*

* Created by on 2019/4/19.*/

public class ThreadPoolMonitor extendsThreadPoolExecutor {private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPoolMonitor.class);/*** 保存任务开始执行的时间,当任务结束时,用任务结束时间减去开始时间计算任务执行时间*/

private ConcurrentHashMapstartTimes;/*** 线程池名称,一般以业务名称命名,方便区分*/

privateString poolName;/*** 调用父类的构造方法,并初始化HashMap和线程池名称

*

*@paramcorePoolSize 线程池核心线程数

*@parammaximumPoolSize 线程池最大线程数

*@paramkeepAliveTime 线程的最大空闲时间

*@paramunit 空闲时间的单位

*@paramworkQueue 保存被提交任务的队列

*@parampoolName 线程池名称*/

public ThreadPoolMonitor(int corePoolSize, int maximumPoolSize, longkeepAliveTime,

TimeUnit unit, BlockingQueueworkQueue, String poolName) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

Executors.defaultThreadFactory(), poolName);

}/*** 调用父类的构造方法,并初始化HashMap和线程池名称

*

*@paramcorePoolSize 线程池核心线程数

*@parammaximumPoolSize 线程池最大线程数

*@paramkeepAliveTime 线程的最大空闲时间

*@paramunit 空闲时间的单位

*@paramworkQueue 保存被提交任务的队列

*@paramthreadFactory 线程工厂

*@parampoolName 线程池名称*/

public ThreadPoolMonitor(int corePoolSize, int maximumPoolSize, longkeepAliveTime,

TimeUnit unit, BlockingQueueworkQueue,

ThreadFactory threadFactory, String poolName) {super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);this.startTimes = new ConcurrentHashMap<>();this.poolName =poolName;

}/*** 线程池延迟关闭时(等待线程池里的任务都执行完毕),统计线程池情况*/@Overridepublic voidshutdown() {//统计已执行任务、正在执行任务、未执行任务数量

LOGGER.info("{} Going to shutdown. Executed tasks: {}, Running tasks: {}, Pending tasks: {}",this.poolName, this.getCompletedTaskCount(), this.getActiveCount(), this.getQueue().size());super.shutdown();

}/*** 线程池立即关闭时,统计线程池情况*/@Overridepublic ListshutdownNow() {//统计已执行任务、正在执行任务、未执行任务数量

LOGGER.info("{} Going to immediately shutdown. Executed tasks: {}, Running tasks: {}, Pending tasks: {}",this.poolName, this.getCompletedTaskCount(), this.getActiveCount(), this.getQueue().size());return super.shutdownNow();

}/*** 任务执行之前,记录任务开始时间*/@Overrideprotected voidbeforeExecute(Thread t, Runnable r) {

startTimes.put(String.valueOf(r.hashCode()),newDate());

}/*** 任务执行之后,计算任务结束时间*/@Overrideprotected voidafterExecute(Runnable r, Throwable t) {

Date startDate=startTimes.remove(String.valueOf(r.hashCode()));

Date finishDate= newDate();long diff = finishDate.getTime() -startDate.getTime();//统计任务耗时、初始线程数、核心线程数、正在执行的任务数量、//已完成任务数量、任务总数、队列里缓存的任务数量、池中存在的最大线程数、//最大允许的线程数、线程空闲时间、线程池是否关闭、线程池是否终止

LOGGER.info("{}-pool-monitor: " +

"Duration: {} ms, PoolSize: {}, CorePoolSize: {}, Active: {}, " +

"Completed: {}, Task: {}, Queue: {}, LargestPoolSize: {}, " +

"MaximumPoolSize: {}, KeepAliveTime: {}, isShutdown: {}, isTerminated: {}",this.poolName,

diff,this.getPoolSize(), this.getCorePoolSize(), this.getActiveCount(),this.getCompletedTaskCount(), this.getTaskCount(), this.getQueue().size(), this.getLargestPoolSize(),this.getMaximumPoolSize(), this.getKeepAliveTime(TimeUnit.MILLISECONDS), this.isShutdown(), this.isTerminated());

}/*** 创建固定线程池,代码源于Executors.newFixedThreadPool方法,这里增加了poolName

*

*@paramnThreads 线程数量

*@parampoolName 线程池名称

*@returnExecutorService对象*/

public static ExecutorService newFixedThreadPool(intnThreads, String poolName) {return new ThreadPoolMonitor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), poolName);

}/*** 创建缓存型线程池,代码源于Executors.newCachedThreadPool方法,这里增加了poolName

*

*@parampoolName 线程池名称

*@returnExecutorService对象*/

public staticExecutorService newCachedThreadPool(String poolName) {return new ThreadPoolMonitor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(), poolName);

}/*** 生成线程池所用的线程,只是改写了线程池默认的线程工厂,传入线程池名称,便于问题追踪*/

static class EventThreadFactory implementsThreadFactory {private static final AtomicInteger poolNumber = new AtomicInteger(1);private finalThreadGroup group;private final AtomicInteger threadNumber = new AtomicInteger(1);private finalString namePrefix;/*** 初始化线程工厂

*

*@parampoolName 线程池名称*/EventThreadFactory(String poolName) {

SecurityManager s=System.getSecurityManager();

group= Objects.nonNull(s) ?s.getThreadGroup() : Thread.currentThread().getThreadGroup();

namePrefix= poolName + "-pool-" + poolNumber.getAndIncrement() + "-thread-";

}

@OverridepublicThread newThread(Runnable r) {

Thread t= new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);if(t.isDaemon())

t.setDaemon(false);if (t.getPriority() !=Thread.NORM_PRIORITY)

t.setPriority(Thread.NORM_PRIORITY);returnt;

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值