清单 3 中的 TrackingThreadPool 演示的是 ThreadPoolExecutor 的一个子 类,它及时给出正在处理中的是哪些任务,以及已经完成的任务的时间统计值。 它通过覆盖 beforeExecute() 和 afterExecute() 挂钩,并提供能检索所搜集 数据的 getter,实现这些任务。
清单 3. 搜集处理中的任务和平均的任务时间统计值的线程池类
public class TrackingThreadPool extends ThreadPoolExecutor {
private final Map<Runnable, Boolean> inProgress
= new ConcurrentHashMap<Runnable,Boolean>();
private final ThreadLocal<Long> startTime = new ThreadLocal<Long>();
private long totalTime;
private int totalTasks;
public TrackingThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
inProgress.put(r, Boolean.TRUE);
startTime.set(new Long(System.currentTimeMillis()));
}
protected void afterExecute(Runnable r, Throwable t) {
long time = System.currentTimeMillis() - startTime.get ().longValue();
synchronized (this) {
totalTime += time;
++totalTasks;
}
inProgress.remove(r);
super.afterExecute(r, t);
}
public Set<Runnable> getInProgressTasks() {
return Collections.unmodifiableSet(inProgress.keySet ());
}
public synchronized int getTotalTasks() {
return totalTasks;
}
public synchronized double getAverageTaskTime() {
return (totalTasks == 0) ? 0 : totalTime / totalTasks;
}
}
Java理论与实践:用JMX检测应用程序(3)
时间:2010-12-20 IBM Brian Goetz
清单 4 中的 ThreadPoolStatusMBean 显示了 TrackingThreadPool 的 MBean 接口,它提供了活动任务、活动线程、完成任务、等候任务的计数,还提 供了当前等候执行和正在执行的任务的列表。在管理接口中包含等候和执行任务 的列表,让您既可以看到应用程序的工作难度,又可以看到它目前的工作内容。 这个特性不仅让您可以洞察应用程序的行为,还能洞察它正在操作的数据集的性 质。
清单 4. TrackingThreadPool 的 MBean 接口
public interface ThreadPoolStatusMBean {
public int getActiveThreads();
public int getActiveTasks();
public int getTotalTasks();
public int getQueuedTasks();
public double getAverageTaskTime();
public String[] getActiveTaskNames();
public String[] getQueuedTaskNames();
}
如果任务的重量级足够,那么甚至可以再进一步,在每个任务提交时都为它 注册一个 MBean (然后在任务完成时再取消注册)。然后可以用管理接口查询 每个任务的当前状态、运行了多长时间,或者请求取消任务。
清单 5 中的 ThreadPoolStatus 实现了 ThreadPoolStatusMBean 接口,它 提供了每个访问器的明显实现。与 MBean 实现类中的典型情况一样,每个操作 实现起来都很细碎,所以把实现委托给了底层受管对象。在这个示例中,JMX 代 码完全独立于受管实体的代码。TrackingThreadPool 对于 JMX 一无所知;通过 为相关的属性提供管理方法和访 |