Menu

Task Statistics Tutorial

Ramon Servadei

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.


Related

Wiki: Tutorial