A ThimbleExecutor can provide statistics covering the number of tasks submitted and executed in an interval. An interval is defined by successive calls to the 'get statistics' methods. It is up to application calling code to define the period for calling the statistics. The code below demonstrates how to gather statistics. In the demonstration 10,000 sequential and coalescing tasks for 2 contexts are run
:::java
public class StatisticsDemo
{
public static void main(String[] args) throws Exception
{
final ThimbleExecutor executor = new ThimbleExecutor(4);
// use a scheduled executor to periodically gather the statistics
ScheduledExecutorService statsService = Executors.newSingleThreadScheduledExecutor();
statsService.scheduleAtFixedRate(new Runnable()
{
@Override
public void run()
{
System.out.println(executor.getSequentialTaskStatistics());
System.out.println(executor.getCoalescingTaskStatistics());
System.out.println(executor.getExecutorStatistics());
System.out.println("--------------------------------------------------------");
}
}, 0, 50, TimeUnit.MILLISECONDS);
final int count = 10000;
final CountDownLatch latch = new CountDownLatch(count * 3);
for (int i = 0; i < count; i++)
{
executor.execute(new ICoalescingRunnable()
{
@Override
public void run()
{
latch.countDown();
}
@Override
public Object context()
{
return "coalescing context 1";
}
});
executor.execute(new ISequentialRunnable()
{
@Override
public void run()
{
latch.countDown();
}
@Override
public Object context()
{
return "sequential context 1";
}
});
executor.execute(new Runnable()
{
@Override
public void run()
{
latch.countDown();
}
});
executor.execute(new ICoalescingRunnable()
{
@Override
public void run()
{
latch.countDown();
}
@Override
public Object context()
{
return "coalescing context 2";
}
});
executor.execute(new ISequentialRunnable()
{
@Override
public void run()
{
latch.countDown();
}
@Override
public Object context()
{
return "sequential context 2";
}
});
}
latch.await();
statsService.shutdown();
Thread.sleep(1000);
System.out.println(executor.getSequentialTaskStatistics());
System.out.println(executor.getCoalescingTaskStatistics());
System.out.println(executor.getStatistics());
}
}
The output shows the toString version of the TaskStatistics objects...
{}
{coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=1, intervalExecuted=0, totalSubmitted=1, totalExecuted=0]}
TaskStatistics [context=ThimbleExecutor, intervalSubmitted=1, intervalExecuted=1, totalSubmitted=1, totalExecuted=1]
--------------------------------------------------------
{sequential context 2=TaskStatistics [context=sequential context 2, intervalSubmitted=3408, intervalExecuted=1628, totalSubmitted=3408, totalExecuted=1628], sequential context 1=TaskStatistics [context=sequential context 1, intervalSubmitted=3409, intervalExecuted=1658, totalSubmitted=3409, totalExecuted=1658]}
{coalescing context 2=TaskStatistics [context=coalescing context 2, intervalSubmitted=3427, intervalExecuted=681, totalSubmitted=3427, totalExecuted=681], coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=3427, intervalExecuted=679, totalSubmitted=3428, totalExecuted=679]}
TaskStatistics [context=ThimbleExecutor, intervalSubmitted=17189, intervalExecuted=8084, totalSubmitted=17190, totalExecuted=8085]
--------------------------------------------------------
{sequential context 2=TaskStatistics [context=sequential context 2, intervalSubmitted=4446, intervalExecuted=5516, totalSubmitted=7854, totalExecuted=7144], sequential context 1=TaskStatistics [context=sequential context 1, intervalSubmitted=4446, intervalExecuted=5605, totalSubmitted=7855, totalExecuted=7263]}
{coalescing context 2=TaskStatistics [context=coalescing context 2, intervalSubmitted=4477, intervalExecuted=1513, totalSubmitted=7904, totalExecuted=2194], coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=4476, intervalExecuted=1483, totalSubmitted=7904, totalExecuted=2162]}
TaskStatistics [context=ThimbleExecutor, intervalSubmitted=24590, intervalExecuted=19477, totalSubmitted=41780, totalExecuted=27562]
--------------------------------------------------------
{sequential context 2=TaskStatistics [context=sequential context 2, intervalSubmitted=2146, intervalExecuted=2856, totalSubmitted=10000, totalExecuted=10000], sequential context 1=TaskStatistics [context=sequential context 1, intervalSubmitted=2145, intervalExecuted=2737, totalSubmitted=10000, totalExecuted=10000]}
{coalescing context 2=TaskStatistics [context=coalescing context 2, intervalSubmitted=2096, intervalExecuted=605, totalSubmitted=10000, totalExecuted=2799], coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=2096, intervalExecuted=677, totalSubmitted=10000, totalExecuted=2839]}
TaskStatistics [context=ThimbleExecutor, intervalSubmitted=8220, intervalExecuted=8006, totalSubmitted=50000, totalExecuted=35568]
Looking at the final statistics in the output, we get the total statistics as follows:
| context | total submitted | total executed |
|---|---|---|
| sequential context 1 | 10000 | 10000 |
| sequential context 2 | 10000 | 10000 |
| coalescing context 1 | 10000 | 2839 |
| coalescing context 2 | 10000 | 2799 |
| total for executor | 50000 | 35568 |
Note that the individual statistics can be obtained using getXXX methods on the TaskStatistics object (see code javadocs). This can be used to produce CSV style data that can be plotted using spreadsheet software to produce a graph of the executor performance.