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; } }
| public interface ThreadPoolStatusMBean { public int getActiveThreads(); public int getActiveTasks(); public int getTotalTasks(); public int getQueuedTasks(); public double getAverageTaskTime(); public String[] getActiveTaskNames(); public String[] getQueuedTaskNames(); } |
public class ThreadPoolStatus implements ThreadPoolStatusMBean { private final TrackingThreadPool pool; public ThreadPoolStatus(TrackingThreadPool pool) { this.pool = pool; } public int getActiveThreads() { return pool.getPoolSize(); } public int getActiveTasks() { return pool.getActiveCount(); } public int getTotalTasks() { return pool.getTotalTasks(); } public int getQueuedTasks() { return pool.getQueue().size(); } public double getAverageTaskTime() { return pool.getAverageTaskTime(); } public String[] getActiveTaskNames() { return toStringArray(pool.getInProgressTasks()); } public String[] getQueuedTaskNames() { return toStringArray(pool.getQueue()); } private String[] toStringArray(Collection<Runnable> collection) { ArrayList<String> list = new ArrayList<String>(); for (Runnable r : collection) list.add(r.toString()); return list.toArray(new String[0]); } }
| public class FetchTask implements Runnable { private final String name; public FetchTask(String name) { this.name = name; } public String toString() { return "FetchTask: " + name; } public void run() { /* Fetch remote resource */ } } |
