线程池监控2-监控线程池状态、线程数量和队列任务数量等

news/2024/10/10 12:21:55/文章来源:https://www.cnblogs.com/xkzhangsanx/p/18456054

1.实现原理

  这篇博文是基于线程池监控1-监控任务执行时间,原理是:创建一个固定时间间隔执行的线程,来记录线程池的池状态、线程数量和队列任务数量等,具体方案:使用单例类缓存所有创建的线程池对象,类创建时启动定时任务线程,定期遍历缓存中线程池,记录线程池信息。

2.实现代码

package com.xkzhangsan.thread.pool.monitor;import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** 全局监控 <br>* 1.定期记录线程池基本信息 <br>** @author xkzhangsan*/
public class GlobalMonitor {private static volatile GlobalMonitor instance;private static final ConcurrentHashMap<String, ThreadPoolMonitor> threadPoolMonitorMap = new ConcurrentHashMap<>();private static final ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);private GlobalMonitor() {scheduledThreadPoolExecutor.scheduleAtFixedRate(new PoolInfoRunnable(), 10, 10, TimeUnit.SECONDS);}public static GlobalMonitor getInstance() {if (instance == null) {synchronized (GlobalMonitor.class) {if (instance == null) {instance = new GlobalMonitor();}}}return instance;}public void put(String poolName, ThreadPoolMonitor threadPoolMonitor) {threadPoolMonitorMap.put(poolName, threadPoolMonitor);}public void remove(String poolName) {threadPoolMonitorMap.remove(poolName);}static class PoolInfoRunnable implements Runnable {@Overridepublic void run() {threadPoolMonitorMap.forEach((poolName, threadPoolMonitor) -> {int currentPoolSize = threadPoolMonitor.getPoolSize();int queueSize = threadPoolMonitor.getQueue().size();System.out.println("poolName:" + poolName + " status:" + threadPoolMonitor.getStatus() + " corePoolSize:" + threadPoolMonitor.getCorePoolSize() + " maximumPoolSize:"+ threadPoolMonitor.getMaximumPoolSize() + " currentPoolSize:" + currentPoolSize + " queueCapacity:" + threadPoolMonitor.getQueueCapacity()+ " queueSize:" + queueSize);});}}}

 

获取线程池状态

这里参考了ThreadPoolExecutor的toString(),返回Running、Shutting down、Terminated 三种状态。

见:ThreadPoolMonitor类

    public String getStatus() {if (super.isTerminated()) {return "Terminated";} else if (super.isShutdown()) {return "Shutting down";} else {return "Running";}}

获取队列总容量

创建ThreadPoolExecutor时,传入的BlockingQueue<Runnable> workQueue,无法直接获取总容量,ThreadPoolExecutor又没有直接获取总容量的方法,
这里想到另一个方法,Queue的remainingCapacity()返回当前队列剩余容量,原理:总容量-队列size,所以,在刚创建时size为0,返回的就时总容量。
见:ThreadPoolMonitor类

    private void init(String poolName, MonitorLevelEnum monitorLevel) {this.poolName = poolName;this.monitorLevel = monitorLevel;this.taskStartTimeMap = new ConcurrentHashMap<>();if (isPoolMonitor()) {GlobalMonitor.getInstance().put(poolName, this);}this.queueCapacity = super.getQueue().remainingCapacity();}public int getQueueCapacity() {return this.queueCapacity;}


3.测试运行

3.1 测试代码

package com.xkzhangsan.thread.pool.monitor;import com.xkzhangsan.thread.pool.monitor.constant.MonitorLevelEnum;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;public class ThreadPoolMonitorTest {public static void main(String[] args) {poolMonitor();}public static void poolMonitor() {ThreadPoolMonitor threadPoolMonitor = new ThreadPoolMonitor(1, 3, 0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(1000), "test", MonitorLevelEnum.POOL);for (int i = 0; i < 100; i++) {int finalI = i;threadPoolMonitor.execute(() -> {try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(finalI);});}threadPoolMonitor.shutdown();}
}

 

3.2 测试结果

0
1
2
poolName:test status:Shutting down corePoolSize:1 maximumPoolSize:3 currentPoolSize:1 queueCapacity:1000 queueSize:96
3
4
5
poolName:test status:Shutting down corePoolSize:1 maximumPoolSize:3 currentPoolSize:1 queueCapacity:1000 queueSize:93
6
7
8
poolName:test status:Shutting down corePoolSize:1 maximumPoolSize:3 currentPoolSize:1 queueCapacity:1000 queueSize:90
9
线程sleep 3s,监控日志10s打印一次,队列中的任务在不断减少。
源代码地址:https://github.com/xkzhangsan/thread-pool-monitor


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/811014.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搭建Redis哨兵集群并使用RedisTemplate实现读写分离

一、理论相关通过上篇博客:搭建Redis“主-从-从”模式集群并使用 RedisTemplate 实现读写分离,我们已经搭建好了Redis“主-从-从”模式集群并且实现读写分离,这里会出现几个问题:如果主库宕机了,我们就需要运行一个新主库,比如说把一个从库切换为主库,把它当成主库。这就…

唯一客服浏览器插件: 视频号直播自动回复与循环发送话术-自动化插件

唯一客服浏览器插件 gofly.v1kf.com 我们在做视频号直播的时候,会有这种自动回复咨询问题的功能唯一客服浏览器插件现在就支持,在视频号直播后台,自动化回复用户问题,以及循环发送我们的介绍话术 十年开发经验程序员,离职全心创业中,历时三年开发出的产品《唯一客服系统》…

[编程笔记] 当前上下文中不存在名称ViewBag

当前上下文中不存在名称"ViewBag",很多ViewBag、@Html.Partial、@Html.FunctionBar() 等这些地方都报波浪线了,提示不存在这个名称,但是代码是可以运行的最近在弄另外一个项目,很长一段时间没接触MVC了,Visual Studio 2022识别cshtml文件的时候,出了一点故障!…

MSSQL-从字符串转换日期和/或时间时,转换失败

1、报错的sql为: select ID,Test_time as 时间, from ProcessData where convert(datetime,test_time,120) between convert(datetime, 2020-10-10, 120) and convert(datetime, 2024-10-11, 120) 它是将Test_time转化为datetime格式,再用between进行比较; 2、报错原因:…

Pytorch常用代码段汇总

Pytorch常用代码段来源: https://zhuanlan.zhihu.com/p/104019160 PyTorch最好的资料是官方文档。本文是PyTorch常用代码段,在参考资料[1](张皓:PyTorch Cookbook)的基础上做了一些修补,方便使用时查阅。 1. 基本配置 导入包和版本查询 import torch import torch.nn as nn…

manim边学边做--无向图

无向图属于数学中的图论这一学科, 所谓无向图G,就是由顶点集V(非空集合)和边集E(由V中元素构成的无序二元组的集合)组成的图, 可表示为G=(V,E)。 在无向图中,边没有方向,即从顶点A到顶点B的边与从顶点B到顶点A的边是相同的。 无向图简洁直观,常用于描述社交网络,交通…

[持续更新]程序员每天会阅读哪些技术网站(带链接)来提升自己?

本文原文来自[持续更新]程序员每天会阅读哪些技术网站(带链接)来提升自己? 国内的网站 这些国内技术网站和社区涵盖了编程语言、算法、职业规划、云计算、AI等多方面的内容,可以获取最新的技术资讯、学习资源和开发经验。当然目前国内的技术社区的内容还是相当的鱼龙混杂。CS…

PEPPA_CTH_PIG

你好CTH近日,有一PEPPA_HACKER_PIG黑入了某不知名CTH的博客,发现其博客荒凉至极,发怒而去,遂留此文,以记之。。。 这博客甚至连个分类也没有,只能我建一个了;

VScode远程访问虚拟机

下载vscode插件Remote Development 该插件包括了wsl,remote ssh 等四个插件,均是用于远程访问虚拟机。 通过ssh访问虚拟机 下载后在工具栏索引可以看到如下标识,按顺序点击进入,然后在“3”显示的搜索框通过“ ssh username@ipAddr”访问,这是方法一。 方法二,还可以通…

20222317 2024-2025-1《网络与系统攻防技术》实验一实验报告

一、实验内容 本次实验的对象是一个名为pwn1的linux可执行文件。该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们本次实验将学习两种方…

似然

似然问题背景:我们观察到随机变量 \(Y\) 的值 \(y\),而 \(Y\) 的概率密度函数 \(f(y; \theta)\) 已知,但依赖于参数 \(\theta\)。 参数 \(\theta\) 来自参数空间 \(\Theta\),观测数据来自样本空间 \(\mathcal{Y}\)。 目标是根据观测数据 \(y\),推断参数 \(\theta\) 的可能…

05-蓝图(Blueprints)

Flask 的蓝图(Blueprints)是一种组织代码的机制,允许你将 Flask 应用分解成多个模块。这样可以更好地组织应用逻辑,使得应用更具可维护性和可扩展性。 每个蓝图可以有自己的路由、视图函数、模板和静态文件,这样可以将相关的功能分组。 通过使用蓝图,你可以将 Flask 应用…