当前位置: 首页 > 科技观察

线程池监控:执行超时、等待超时;执行超时次数,等待超时次数

时间:2023-03-18 11:23:25 科技观察

监控线程池:执行超时,等待超时;定义RunnableRecord关键节点时间关键时间节点参数:任务创建(提交)时间:submitTime任务开始执行时间:startExeTime任务结束执行时间:endExeTime任务在队列中等待时间:任务开始执行时间-任务创建(提交)时间任务执行总时间:任务结束执行时间-任务开始执行时间源码分析线程池ThreadPoolExecutor为了提供扩展,提供了beforeExecute和afterExecute两个方法。这两个方法在每次任务执行前后都会调用,相当于给线程任务执行做了一个切入。publicclassThreadPoolExecutorextendsAbstractExecutorService{/***@paramt执行任务的线程*@paramprotectedvoidbeforeExecute(Threadt,Runnabler){}/***@paramr要执行的任务*@paramprotectedvoidafterExecute(Runnabler,Throwablet){}}源码执行逻辑:线程池扩展代码:publicclassThreadPoolExpandTest{//定义线程池publicstaticThreadPoolExecutorpoolExecutor=newThreadPoolExecutor(2,4,60,TimeUnit.SECONDS,newArrayBlockingQueue<>(5),newThreadPoolExecutor.DiscardOldestPolicy()){@Override/***@paramt执行任务的线程*@paramprotectedvoidbeforeExecute(Threadt,Runnabler){System.out.println("beforeExecute将被执行");}/***@paramr要执行的任务*@param@OverrideprotectedvoidafterExecute(Runnabler,Throwablet){System.out.println("afterExecute已经执行");}};民众staticvoidmain(String[]args){poolExecutor.execute(()->{System.out.println("任务执行");});}}运行结果:beforeExecute执行任务执行afterExecute执行总结:从测试代码可以看出,可以通过扩展线程池参数来监控任务执行自定义Runnable通过自定义Runnable,记录任务执行的一些时间:任务创建(提交)时间任务开始执行时间publicclassDynamicRunnableimplementsRunnable{/***runnable*/privatefinalRunnablerunnable;/***任务创建(提交)时间*/privatefinalLongsubmitTime;/***任务开始执行时间*/privateLongstartExeTime;publicDynamicRunnable(Runnablerunnable){this.runnable=runnable;submitTime=System.currentTimeMillis();}@Overridepublicvoidrun(){runnable.run();}publicLonggetSubmitTime(){返回提交时间;}publicvoidsetStartExeTime(LongstartExeTime){this.startExeTime=startExeTime;}publicLonggetStartExeTime(){返回startExeTime;}}继承线程池+CustomRunnable核心参数:/***执行超时,单位(毫秒)*/privatelongrunTimeout;/***等待超时,单位(毫秒)*/privatelongqueueTimeout;/***执行超时次数*/privatefinalAtomicIntegerrunTimeoutCount=newAtomicInteger();/***等待超时次数*/privatefinalAtomicIntegerqueueTimeoutCount=newAtomicInteger();重写ThreadPoolExecutormethod:@Overridepublicvoidexecute(Runnablecommand){if(runTimeout>0||queueTimeout>0){//记录任务提交时间command=newDynamicRunnable(command);}super.execute(command);}@OverrideprotectedvoidbeforeExecute(Threadt,Runnabler){if(!(rinstanceofDynamicRunnable)){super.beforeExecute(t,r);返回;}DynamicRunnablerunnable=(DynamicRunnable)r;longcurrTime=System.currentTimeMillis();if(runTimeout>0){//记录任务开始执行时间runnable.setStartExeTime(currTime);}if(queueTimeout>0){//任务开始执行时间-任务创建(提交)时间longwaitTime=currTime-runnable.getSubmitTime();if(waitTime>queueTimeout){log.error("{}执行队列超时waitTime:{}ms",this.getThreadPoolName(),waitTime);}}super.beforeExecute(t,r);}@OverrideprotectedvoidafterExecute(Runnabler,Throwablet){if(runTimeout>0){DynamicRunnablerunnable=(DynamicRunnable)r;//任务总执行时间:任务结束执行时间-任务开始执行时间longrunTime=System.currentTimeMillis()-runnable.getStartExeTime();if(runTime>runTimeout){runTimeoutCount.incrementAndGet();log.error("{}执行,运行超时runTime:{}ms",this.getThreadPoolName(),runTime);}}super.afterExecute(r,t);}