1.Realization Principle
This blog post is based onThread Pool Monitoring 1-Monitoring Task Execution TimeThe principle is: to create a fixed time interval execution of the thread to record the thread pool pool state, the number of threads and the number of queue tasks , etc., the specific program: the use of a singleton class to cache all the created thread pool objects , class creation start timed task thread , regularly traversing the thread pool in the cache to record the thread pool information.
2.Realization code
package ;
import ;
import ;
import ;
/**
* Global monitoring <br>.
* 1. Record thread pool basic information periodically <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() {
(new PoolInfoRunnable(), 10, 10, );
}
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) {
(poolName, threadPoolMonitor);
}
public void remove(String poolName) {
(poolName);
}
static class PoolInfoRunnable implements Runnable {
@Override
public void run() {
((poolName, threadPoolMonitor) -> {
int currentPoolSize = ();
int queueSize = ().size();
("poolName:" + poolName + " status:" + () + " corePoolSize:" + () + " maximumPoolSize:"
+ () + " currentPoolSize:" + currentPoolSize + " queueCapacity:" + ()
+ " queueSize:" + queueSize);
});
}
}
}
package ; import ; import ; import ; /** * Global monitoring <br>. * 1. Record thread pool basic information periodically <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() { (new PoolInfoRunnable(), 10, 10, ); } 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) { (poolName, threadPoolMonitor); } public void remove(String poolName) { (poolName); } static class PoolInfoRunnable implements Runnable { @Override public void run() { ((poolName, threadPoolMonitor) -> { int currentPoolSize = (); int queueSize = ().size(); ("poolName:" + poolName + " status:" + () + " corePoolSize:" + () + " maximumPoolSize:" + () + " currentPoolSize:" + currentPoolSize + " queueCapacity:" + () + " queueSize:" + queueSize); }); } } }
Getting Thread Pool Status
The reference here is to ThreadPoolExecutor's toString(), which returns Running, Shutting down, and Terminated.
See:ThreadPoolMonitor class
public String getStatus() { if (super.isTerminated()) { return "Terminated"; } else if (super.isShutdown()) { return "Shutting down"; } else { return "Running"; } }
Get the total queue capacity
When creating a ThreadPoolExecutor, the BlockingQueue<Runnable> workQueue, passed in, can't get the total capacity directly, and the ThreadPoolExecutor doesn't have a method to get the total capacity directly.
Here think of another method, Queue's maintainingCapacity () to return the remaining capacity of the current queue, the principle: the total capacity - queue size, so, just created when the size is 0, the return of the total capacity.
See:ThreadPoolMonitor class
private void init(String poolName, MonitorLevelEnum monitorLevel) { this.poolName = poolName; this.monitorLevel = monitorLevel; this.taskStartTimeMap = new ConcurrentHashMap<>(); if (isPoolMonitor()) { ().put(poolName, this); } = super.getQueue().remainingCapacity(); } public int getQueueCapacity() { return this.queueCapacity; }
3. Test Run
3.1 Test code
package ;
import ;
import ;
import ;
public class ThreadPoolMonitorTest {
public static void main(String[] args) {
poolMonitor();
}
public static void poolMonitor() {
ThreadPoolMonitor threadPoolMonitor = new ThreadPoolMonitor(1, 3, 0, , new ArrayBlockingQueue<>(1000), "test", );
for (int i = 0; i < 100; i++) {
int finalI = i;
(() -> {
try {
(3);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
(finalI);
});
}
();
}
}
package ; import ; import ; import ; public class ThreadPoolMonitorTest { public static void main(String[] args) { poolMonitor(); } public static void poolMonitor() { ThreadPoolMonitor threadPoolMonitor = new ThreadPoolMonitor(1, 3, 0, , new ArrayBlockingQueue<>(1000), "test", ); for (int i = 0; i < 100; i++) { int finalI = i; (() -> { try { (3); } catch (InterruptedException e) { throw new RuntimeException(e); } (finalI); }); } (); } }
3.2 Test results
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
threadingsleep 3s,Monitoring Logs10sprint once,Tasks in the queue are decreasing。
source code address:/xkzhangsan/thread-pool-monitor