/
ForkJoinPoolMonitor.java
103 lines (86 loc) · 3.61 KB
/
ForkJoinPoolMonitor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package java.util.concurrent;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.LongAdder;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ForkJoinPoolMonitor implements ForkJoinPoolMonitorMXBean {
private static Logger LOGGER = Logger.getLogger( ForkJoinPoolMonitor.class.getName());
private static AtomicInteger instanceCount = new AtomicInteger(0);
public static String JMX_OBJECT_NAME_BASE = "com.jclarity:type=forkjoinpool,instance=";
{
try {
ObjectName name = new ObjectName( JMX_OBJECT_NAME_BASE + instanceCount.getAndIncrement());
ManagementFactory.getPlatformMBeanServer().registerMBean( this, name);
} catch (InstanceAlreadyExistsException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
} catch (MBeanRegistrationException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
} catch (NotCompliantMBeanException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
} catch (MalformedObjectNameException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
}
}
private ConcurrentHashMap<ForkJoinTask,Long> monitoredTasks = new ConcurrentHashMap<>();
private long startTime = System.nanoTime();
private LongAdder numberOfTasksSubmitted = new LongAdder();
private LongAdder taskRetiredCount = new LongAdder();
private volatile double timeInSystem = 0.0d;
public ForkJoinPoolMonitor() {}
/*****
*
* Monitoring methods
*
*/
public void submitTask(ForkJoinTask task) {
monitoredTasks.put(task, System.nanoTime());
numberOfTasksSubmitted.increment();
}
public void retireTask( ForkJoinTask task) {
try {
this.timeInSystem += (double)(System.nanoTime() - monitoredTasks.remove(task));
this.taskRetiredCount.increment();
} catch (NullPointerException npe) {/*silly but NPE is throws if element isn't in map */}
}
@Override
public long getNumberOfTasksSubmitted() {
return numberOfTasksSubmitted.longValue();
}
@Override
public long getNumberOfTasksRetired() { return taskRetiredCount.longValue(); }
@Override
public double getArrivalIntervalInSeconds() {
return (((double)( System.nanoTime() - startTime)) / 1000000000.0d) / numberOfTasksSubmitted.doubleValue();
}
@Override
public double getAverageTimeInSystem() {
double localTasksRetiredCount = this.taskRetiredCount.doubleValue();
double localTimeInSystem = this.timeInSystem;
if ( localTasksRetiredCount == 0L)
return 0.0d;
return localTimeInSystem / localTasksRetiredCount;
}
@Override
public double averageNumberOfTasksInSystem() {
double localAverageTimeInSystem = getAverageTimeInSystem();
double localArrivalIntervalInSeconds = getArrivalIntervalInSeconds();
if ( localArrivalIntervalInSeconds == 0.0d) {
return 0.0d;
}
return localAverageTimeInSystem / localArrivalIntervalInSeconds;
}
@Override
public void clear() {
this.numberOfTasksSubmitted.reset();
this.taskRetiredCount.reset();
this.timeInSystem = 0.0d;
this.startTime = System.nanoTime();
monitoredTasks.clear();
}
}