gt:                 new Instrument<Double>() {
context: package com.bigdata.util.concurrent;
  
  import java.util.Queue;
  import java.util.concurrent.Callable;
  import java.util.concurrent.ThreadPoolExecutor;
  import java.util.concurrent.TimeUnit;
  
  import org.apache.log4j.Logger;
  
  import com.bigdata.counters.CounterSet;
  import com.bigdata.counters.Instrument;
  import com.bigdata.util.concurrent.IQueueCounters.IThreadPoolExecutorCounters;
  
  /**
   * Class tracks a variety of information about a {@link ThreadPoolExecutor}
   * including the moving average of its queue length, queue size, average active
   * count, etc.
   * 
   * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
   * @version $Id$
   */
  public class ThreadPoolExecutorBaseStatisticsTask implements Runnable {
  
      private static final Logger log = Logger
              .getLogger(ThreadPoolExecutorBaseStatisticsTask.class);
  
      /**
       * The executor service that is being monitored.
       */
      protected final ThreadPoolExecutor service;
  
      /**
       * The time when we started to collect data about the {@link #service} (set
       * by the ctor).
       */
      protected final long startNanos;
      
      /**
       * The weight used to compute the moving average.
       */
      protected final double w;
      
      /*
       * There are several different moving averages which are computed.
       */
      
      /**
       * Scaling factor converts nanoseconds to milliseconds.
       */
      static final double scalingFactor = 1d / TimeUnit.NANOSECONDS.convert(1,
              TimeUnit.MILLISECONDS);
      
      /**
       * 
       * @param service
       *            The service to be monitored.
       */
      public ThreadPoolExecutorBaseStatisticsTask(ThreadPoolExecutor service) {
  
          this(service, MovingAverageTask.DEFAULT_WEIGHT);
  
      }
  
      /**
       * Core impl.
       * 
       * @param service
       *            The service to be monitored.
       * @param w
       *            The weight to be used by the {@link MovingAverageTask}s.
       */
      public ThreadPoolExecutorBaseStatisticsTask(final ThreadPoolExecutor service,
              final double w) {
      
          if (service == null)
              throw new IllegalArgumentException();
  
          if (w <= 0d || w >= 1d)
              throw new IllegalArgumentException();
          
          this.service = service;
          
          this.startNanos = System.nanoTime();
  
          this.w = w;
  
          queueSizeTask = new MovingAverageTask("queueSize",
                  new Callable<Integer>() {
                      public Integer call() {
                          return service.getQueue().size();
                      }
                  }, w);
  
          activeCountTask = new MovingAverageTask("activeCount",
                  new Callable<Integer>() {
                      public Integer call() {
                          return service.getActiveCount();
                      }
                  }, w);
  
          queueLengthTask = new MovingAverageTask("queueLength",
                  new Callable<Integer>() {
                      public Integer call() {
                          return service.getQueue().size()
                                  + service.getActiveCount();
                      }
                  }, w);
  
          poolSizeTask = new MovingAverageTask("poolSize",
                  new Callable<Integer>() {
                      public Integer call() {
                          return service.getPoolSize();
                      }
                  }, w);
  
      }
  
      /**
       * The moving average of {@link Queue#size()} for the
       * {@link ThreadPoolExecutor}'s work queue.
       */
      private final MovingAverageTask queueSizeTask;
      
      /**
       * The moving average of {@link ThreadPoolExecutor#getActiveCount().
       */
      private final MovingAverageTask activeCountTask;
      
      /**
       * The moving average of (queueSize + activeCount).
       */
      private final MovingAverageTask queueLengthTask;
  
      /**
       * The moving average of {@link ThreadPoolExecutor#getPoolSize()}.
       */
      private final MovingAverageTask poolSizeTask;
  
      /**
       * This should be invoked once per second to sample various counters in
       * order to turn their values into moving averages.
       * <p>
       * Note: don't throw anything from here or it will cause the scheduled task
       * executing this to no longer be run!
       */
      public void run() {
  
          try {
  
              queueSizeTask.run();
              
              activeCountTask.run();
              
              queueLengthTask.run();
              
              poolSizeTask.run();
              
          } catch (Exception ex) {
  
              log.error(this,ex);
  
          }
          
      }
  
      /**
       * Return the moving averages and various other counters sampled and
       * reported by this class.
       */
      public CounterSet getCounters() {
  
          final CounterSet counterSet = new CounterSet();
  
          counterSet.addCounter(IThreadPoolExecutorCounters.AverageQueueSize,
                  new Instrument<Double>() {
                      @Override
                      protected void sample() {
                          setValue(queueSizeTask.getMovingAverage());
                      }
                  });
          
          counterSet.addCounter(IThreadPoolExecutorCounters.AverageActiveCount,
                  new Instrument<Double>() {
                      @Override
                      protected void sample() {
                          setValue(activeCountTask.getMovingAverage());
                      }
                  });
  
          counterSet.addCounter(IThreadPoolExecutorCounters.AverageQueueLength,
                  new Instrument<Double>() {
                      @Override
                      protected void sample() {
                          setValue(queueLengthTask.getMovingAverage());
                      }
                  });
          
          // @todo Report iff not being reported via the TaskCounters.
          counterSet.addCounter(IThreadPoolExecutorCounters.TaskCompleteCount,
                  new Instrument<Long>() {
                      public void sample() {
                          setValue(service.getCompletedTaskCount());
                      }
                  });
  
          counterSet.addCounter(IThreadPoolExecutorCounters.PoolSize,
  