<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to Tutorial</title><link>https://sourceforge.net/p/thimble/wiki/Tutorial/</link><description>Recent changes to Tutorial</description><atom:link href="https://sourceforge.net/p/thimble/wiki/Tutorial/feed" rel="self"/><language>en</language><lastBuildDate>Sun, 09 Dec 2012 16:12:56 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/thimble/wiki/Tutorial/feed" rel="self" type="application/rss+xml"/><item><title>WikiPage Tutorial modified by Ramon Servadei</title><link>https://sourceforge.net/p/thimble/wiki/Tutorial/</link><description>&lt;pre&gt;--- v6
+++ v7
@@ -1,446 +1,8 @@
 # Thimble "Hello World" Tutorial #
 
-This tutorial will take you through all the features of Thimble. 
+The following tutorial pages will take you through all the features of Thimble:
+[Sequential Task Tutorial]
+[Coalescing Task Tutorial]
+[Task Statistics Tutorial]
 
-[TOC]
 
-## Sequential task demonstration ##
-
-This tutorial will demonstrate how a ThimbleExecutor executes sequential tasks. The code below runs a sequential task in a 4-thread ThimbleExecutor.
-
-~~~~~
-:::java
-public class TestSequential
-{
-    public static void main(String[] args) throws Exception
-    {
-        Executor executor = new ThimbleExecutor(4);
-        final int count = 10;
-        final CountDownLatch latch = new CountDownLatch(count * 2);
-        for (int i = 0; i &lt; count; i++)
-        {
-            final int myCount = i;
-            
-            executor.execute(new ISequentialRunnable()
-            {
-                @Override
-                public void run()
-                {
-                    System.out.println("HelloWorld (context 1) " + myCount);
-                    latch.countDown();
-                }
-                
-                @Override
-                public Object context()
-                {
-                    return "context1";
-                }
-            });
-            
-            executor.execute(new ISequentialRunnable()
-            {
-                @Override
-                public void run()
-                {
-                    System.out.println("HelloWorld (context 2) " + myCount);
-                    latch.countDown();
-                }
-                
-                @Override
-                public Object context()
-                {
-                    return "context2";
-                }
-            });
-        }
-        latch.await();        
-    }
-}
-~~~~~
-
-The output demonstrates that the tasks are executed in order. Notice that there is some inter-leaving for the execution of the sequential tasks between context 1 and context 2 but that both contexts have their tasks executed in sequence.
-
-~~~~~
-HelloWorld (context 1) 0
-HelloWorld (context 1) 1
-HelloWorld (context 2) 0
-HelloWorld (context 1) 2
-HelloWorld (context 2) 1
-HelloWorld (context 1) 3
-HelloWorld (context 2) 2
-HelloWorld (context 1) 4
-HelloWorld (context 2) 3
-HelloWorld (context 1) 5
-HelloWorld (context 2) 4
-HelloWorld (context 1) 6
-HelloWorld (context 2) 5
-HelloWorld (context 1) 7
-HelloWorld (context 2) 6
-HelloWorld (context 1) 8
-HelloWorld (context 2) 7
-HelloWorld (context 1) 9
-HelloWorld (context 2) 8
-HelloWorld (context 2) 9
-~~~~~
-
-Compare this with using a standard multi-thread executor
-
-~~~~~
-:::java
-public class TestSequentialWithStandardExecutor
-{
-    public static void main(String[] args) throws Exception
-    {
-        Executor executor = Executors.newFixedThreadPool(4);
-        final int count = 10;
-        final CountDownLatch latch = new CountDownLatch(count * 2);
-        for (int i = 0; i &lt; count; i++)
-        {
-            final int myCount = i;
-            
-            executor.execute(new ISequentialRunnable()
-            {
-                @Override
-                public void run()
-                {
-                    System.out.println("HelloWorld (context 1) " + myCount);
-                    latch.countDown();
-                }
-                
-                @Override
-                public Object context()
-                {
-                    return "context1";
-                }
-            });
-            
-            executor.execute(new ISequentialRunnable()
-            {
-                @Override
-                public void run()
-                {
-                    System.out.println("HelloWorld (context 2) " + myCount);
-                    latch.countDown();
-                }
-                
-                @Override
-                public Object context()
-                {
-                    return "context2";
-                }
-            });
-        }
-        latch.await();        
-    }
-}
-~~~~~
-
-The output shows that the tasks are executed non-sequentially.
-
-~~~~~
-HelloWorld (context 1) 0
-HelloWorld (context 2) 0
-HelloWorld (context 1) 2
-HelloWorld (context 1) 3
-HelloWorld (context 2) 2
-HelloWorld (context 1) 4
-HelloWorld (context 2) 4
-HelloWorld (context 2) 1
-HelloWorld (context 2) 5
-HelloWorld (context 2) 3
-HelloWorld (context 1) 6
-HelloWorld (context 1) 5
-HelloWorld (context 2) 7
-HelloWorld (context 1) 8
-HelloWorld (context 1) 1
-HelloWorld (context 2) 8
-HelloWorld (context 1) 7
-HelloWorld (context 2) 6
-HelloWorld (context 2) 9
-HelloWorld (context 1) 9
-~~~~~
-
-### Conclusion ###
-This demonstrates that a single ThimbleExecutor could be used to handle sequential tasks. In situations where tasks for multiple contexts need to be executed in sequence, rather than having a single-thread per context, a single multi-thread ThimbleExecutor can be used.
-
-## Coalescing task demonstration ##
-
-Now we will look at how a ThimbleExecutor handles coalescing tasks. Coalescing tasks are tasks where a later task can overwrite a previous submitted task that has not executed yet. The code below executes 100 coalescing tasks in a 4-thread ThimbleExecutor.
-
-~~~~~
-:::java
-public class TestCoalescing
-{
-    public static void main(String[] args) throws Exception
-    {
-        Executor executor = new ThimbleExecutor(4);
-        final int count = 100;
-        final CountDownLatch latch = new CountDownLatch(count * 2);
-        for (int i = 0; i &lt; count; i++)
-        {
-            final int myCount = i;
-            
-            executor.execute(new ICoalescingRunnable()
-            {
-                @Override
-                public void run()
-                {
-                    System.out.println("HelloWorld (context 1) " + myCount);
-                    latch.countDown();
-                }
-                
-                @Override
-                public Object context()
-                {
-                    return "context1";
-                }
-            });
-            
-            executor.execute(new ICoalescingRunnable()
-            {
-                @Override
-                public void run()
-                {
-                    System.out.println("HelloWorld (context 2) " + myCount);
-                    latch.countDown();
-                }
-                
-                @Override
-                public Object context()
-                {
-                    return "context2";
-                }
-            });
-        }
-        latch.await();        
-    }
-}
-~~~~~
-
-The output shows that not every submitted task is run but it is always a later task that is run (never a former one). Indeed only about 1/10th of the tasks per context are executed. Coalescing tasks are useful in situations where a high-frequency producer is scheduling tasks where logically only the latest task at any point in time needs to be executed. This can drastically improve throughput performance.
-
-~~~~~
-HelloWorld (context 1) 0
-HelloWorld (context 2) 4
-HelloWorld (context 1) 28
-HelloWorld (context 1) 32
-HelloWorld (context 2) 35
-HelloWorld (context 2) 42
-HelloWorld (context 1) 38
-HelloWorld (context 2) 50
-HelloWorld (context 1) 56
-HelloWorld (context 1) 59
-HelloWorld (context 1) 61
-HelloWorld (context 1) 67
-HelloWorld (context 2) 67
-HelloWorld (context 1) 72
-HelloWorld (context 2) 82
-HelloWorld (context 2) 89
-HelloWorld (context 2) 95
-HelloWorld (context 1) 97
-HelloWorld (context 2) 99
-HelloWorld (context 1) 99
-~~~~~
-
-Compare with using a standard 4-thread executor.
-
-~~~~~
-:::java
-public class TestCoalescingWithStandardExecutor
-{
-    public static void main(String[] args) throws Exception
-    {
-        Executor executor = Executors.newFixedThreadPool(4);
-        final int count = 100;
-        final CountDownLatch latch = new CountDownLatch(count * 2);
-        for (int i = 0; i &lt; count; i++)
-        {
-            final int myCount = i;
-            
-            executor.execute(new ICoalescingRunnable()
-            {
-                @Override
-                public void run()
-                {
-                    System.out.println("HelloWorld (context 1) " + myCount);
-                    latch.countDown();
-                }
-                
-                @Override
-                public Object context()
-                {
-                    return "context1";
-                }
-            });
-            
-            executor.execute(new ICoalescingRunnable()
-            {
-                @Override
-                public void run()
-                {
-                    System.out.println("HelloWorld (context 2) " + myCount);
-                    latch.countDown();
-                }
-                
-                @Override
-                public Object context()
-                {
-                    return "context2";
-                }
-            });
-        }
-        latch.await();        
-    }
-}
-~~~~~
-
-The output shows that every task is run and also not in order.
-
-~~~~~
-HelloWorld (context 1) 0
-HelloWorld (context 1) 2
-HelloWorld (context 2) 2
-HelloWorld (context 1) 3
-HelloWorld (context 2) 3
-HelloWorld (context 1) 4
-HelloWorld (context 2) 4
-HelloWorld (context 1) 5
-HelloWorld (context 2) 5
-HelloWorld (context 1) 6
-HelloWorld (context 2) 6
-...
-HelloWorld (context 2) 96
-HelloWorld (context 1) 97
-HelloWorld (context 2) 97
-HelloWorld (context 1) 98
-HelloWorld (context 2) 98
-HelloWorld (context 1) 99
-HelloWorld (context 2) 99
-HelloWorld (context 1) 69
-HelloWorld (context 1) 75
-HelloWorld (context 2) 74
-~~~~~
-
-### Conclusion ###
-Executing coalescing tasks using a ThimbleExecutor provides an efficient way of handling fast-producer situations where the data being produced can be coalesced.
-
-## Task statistics
-
-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.getStatistics());
-            }
-        }, 0, 50, TimeUnit.MILLISECONDS);
-
-        final int count = 10000;
-        final CountDownLatch latch = new CountDownLatch(count * 3);
-        for (int i = 0; i &lt; 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();
-
-        System.out.println(executor.getSequentialTaskStatistics());
-        System.out.println(executor.getCoalescingTaskStatistics());
-        System.out.println(executor.getStatistics());
-    }
-}
-~~~~~
-
-The output
-
-~~~~~
-{coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=1, intervalExecuted=0, totalSubmitted=1, totalExecuted=0]}
-TaskStatistics [context=ThimbleExecutor, intervalSubmitted=1, intervalExecuted=0, totalSubmitted=1, totalExecuted=0]
-{sequential context 2=TaskStatistics [context=sequential context 2, intervalSubmitted=2408, intervalExecuted=1921, totalSubmitted=2408, totalExecuted=1921], sequential context 1=TaskStatistics [context=sequential context 1, intervalSubmitted=2409, intervalExecuted=2092, totalSubmitted=2409, totalExecuted=2092]}
-{coalescing context 2=TaskStatistics [context=coalescing context 2, intervalSubmitted=2435, intervalExecuted=179, totalSubmitted=2435, totalExecuted=179], coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=2434, intervalExecuted=294, totalSubmitted=2435, totalExecuted=294]}
-TaskStatistics [context=ThimbleExecutor, intervalSubmitted=12318, intervalExecuted=6882, totalSubmitted=12319, totalExecuted=6882]
-{sequential context 2=TaskStatistics [context=sequential context 2, intervalSubmitted=3680, intervalExecuted=4167, totalSubmitted=6088, totalExecuted=6088], sequential context 1=TaskStatistics [context=sequential context 1, intervalSubmitted=3679, intervalExecuted=3996, totalSubmitted=6088, totalExecuted=6088]}
-{coalescing context 2=TaskStatistics [context=coalescing context 2, intervalSubmitted=3668, intervalExecuted=1212, totalSubmitted=6103, totalExecuted=1391], coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=3668, intervalExecuted=926, totalSubmitted=6103, totalExecuted=1220]}
-TaskStatistics [context=ThimbleExecutor, intervalSubmitted=18259, intervalExecuted=14036, totalSubmitted=30578, totalExecuted=20918]
-{sequential context 2=TaskStatistics [context=sequential context 2, intervalSubmitted=3912, intervalExecuted=3912, totalSubmitted=10000, totalExecuted=10000], sequential context 1=TaskStatistics [context=sequential context 1, intervalSubmitted=3912, intervalExecuted=3912, totalSubmitted=10000, totalExecuted=10000]}
-{coalescing context 2=TaskStatistics [context=coalescing context 2, intervalSubmitted=3897, intervalExecuted=1936, totalSubmitted=10000, totalExecuted=3327], coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=3897, intervalExecuted=1893, totalSubmitted=10000, totalExecuted=3113]}
-TaskStatistics [context=ThimbleExecutor, intervalSubmitted=19421, intervalExecuted=15500, totalSubmitted=49999, totalExecuted=36418]
-~~~~~
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ramon Servadei</dc:creator><pubDate>Sun, 09 Dec 2012 16:12:56 -0000</pubDate><guid>https://sourceforge.nete75417038ddfe8f09304c237181c685ebc9384d8</guid></item><item><title>WikiPage Tutorial modified by Ramon Servadei</title><link>https://sourceforge.net/p/thimble/wiki/Tutorial/</link><description>&lt;pre&gt;--- v5
+++ v6
@@ -328,3 +328,119 @@
 
 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.getStatistics());
+            }
+        }, 0, 50, TimeUnit.MILLISECONDS);
+
+        final int count = 10000;
+        final CountDownLatch latch = new CountDownLatch(count * 3);
+        for (int i = 0; i &lt; 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();
+
+        System.out.println(executor.getSequentialTaskStatistics());
+        System.out.println(executor.getCoalescingTaskStatistics());
+        System.out.println(executor.getStatistics());
+    }
+}
+~~~~~
+
+The output
+
+~~~~~
+{coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=1, intervalExecuted=0, totalSubmitted=1, totalExecuted=0]}
+TaskStatistics [context=ThimbleExecutor, intervalSubmitted=1, intervalExecuted=0, totalSubmitted=1, totalExecuted=0]
+{sequential context 2=TaskStatistics [context=sequential context 2, intervalSubmitted=2408, intervalExecuted=1921, totalSubmitted=2408, totalExecuted=1921], sequential context 1=TaskStatistics [context=sequential context 1, intervalSubmitted=2409, intervalExecuted=2092, totalSubmitted=2409, totalExecuted=2092]}
+{coalescing context 2=TaskStatistics [context=coalescing context 2, intervalSubmitted=2435, intervalExecuted=179, totalSubmitted=2435, totalExecuted=179], coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=2434, intervalExecuted=294, totalSubmitted=2435, totalExecuted=294]}
+TaskStatistics [context=ThimbleExecutor, intervalSubmitted=12318, intervalExecuted=6882, totalSubmitted=12319, totalExecuted=6882]
+{sequential context 2=TaskStatistics [context=sequential context 2, intervalSubmitted=3680, intervalExecuted=4167, totalSubmitted=6088, totalExecuted=6088], sequential context 1=TaskStatistics [context=sequential context 1, intervalSubmitted=3679, intervalExecuted=3996, totalSubmitted=6088, totalExecuted=6088]}
+{coalescing context 2=TaskStatistics [context=coalescing context 2, intervalSubmitted=3668, intervalExecuted=1212, totalSubmitted=6103, totalExecuted=1391], coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=3668, intervalExecuted=926, totalSubmitted=6103, totalExecuted=1220]}
+TaskStatistics [context=ThimbleExecutor, intervalSubmitted=18259, intervalExecuted=14036, totalSubmitted=30578, totalExecuted=20918]
+{sequential context 2=TaskStatistics [context=sequential context 2, intervalSubmitted=3912, intervalExecuted=3912, totalSubmitted=10000, totalExecuted=10000], sequential context 1=TaskStatistics [context=sequential context 1, intervalSubmitted=3912, intervalExecuted=3912, totalSubmitted=10000, totalExecuted=10000]}
+{coalescing context 2=TaskStatistics [context=coalescing context 2, intervalSubmitted=3897, intervalExecuted=1936, totalSubmitted=10000, totalExecuted=3327], coalescing context 1=TaskStatistics [context=coalescing context 1, intervalSubmitted=3897, intervalExecuted=1893, totalSubmitted=10000, totalExecuted=3113]}
+TaskStatistics [context=ThimbleExecutor, intervalSubmitted=19421, intervalExecuted=15500, totalSubmitted=49999, totalExecuted=36418]
+~~~~~
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ramon Servadei</dc:creator><pubDate>Sun, 09 Dec 2012 16:07:49 -0000</pubDate><guid>https://sourceforge.net7f54aa82449e70fd4ed9178cbf1b434de9a2f961</guid></item><item><title>WikiPage Tutorial modified by Ramon Servadei</title><link>https://sourceforge.net/p/thimble/wiki/Tutorial/</link><description>&lt;pre&gt;--- v4
+++ v5
@@ -1,10 +1,10 @@
-# Thimble "Hello World" Tutorial
+# Thimble "Hello World" Tutorial #
 
 This tutorial will take you through all the features of Thimble. 
 
 [TOC]
 
-## Sequential task demonstration
+## Sequential task demonstration ##
 
 This tutorial will demonstrate how a ThimbleExecutor executes sequential tasks. The code below runs a sequential task in a 4-thread ThimbleExecutor.
 
@@ -16,7 +16,7 @@
     {
         Executor executor = new ThimbleExecutor(4);
         final int count = 10;
-        final CountDownLatch latch = new CountDownLatch(count);
+        final CountDownLatch latch = new CountDownLatch(count * 2);
         for (int i = 0; i &lt; count; i++)
         {
             final int myCount = i;
@@ -62,25 +62,25 @@
 
 ~~~~~
 HelloWorld (context 1) 0
+HelloWorld (context 1) 1
 HelloWorld (context 2) 0
-HelloWorld (context 1) 1
+HelloWorld (context 1) 2
 HelloWorld (context 2) 1
-HelloWorld (context 1) 2
+HelloWorld (context 1) 3
 HelloWorld (context 2) 2
+HelloWorld (context 1) 4
 HelloWorld (context 2) 3
+HelloWorld (context 1) 5
 HelloWorld (context 2) 4
+HelloWorld (context 1) 6
 HelloWorld (context 2) 5
+HelloWorld (context 1) 7
 HelloWorld (context 2) 6
+HelloWorld (context 1) 8
 HelloWorld (context 2) 7
+HelloWorld (context 1) 9
 HelloWorld (context 2) 8
 HelloWorld (context 2) 9
-HelloWorld (context 1) 3
-HelloWorld (context 1) 4
-HelloWorld (context 1) 5
-HelloWorld (context 1) 6
-HelloWorld (context 1) 7
-HelloWorld (context 1) 8
-HelloWorld (context 1) 9
 ~~~~~
 
 Compare this with using a standard multi-thread executor
@@ -93,7 +93,7 @@
     {
         Executor executor = Executors.newFixedThreadPool(4);
         final int count = 10;
-        final CountDownLatch latch = new CountDownLatch(count);
+        final CountDownLatch latch = new CountDownLatch(count * 2);
         for (int i = 0; i &lt; count; i++)
         {
             final int myCount = i;
@@ -140,30 +140,30 @@
 ~~~~~
 HelloWorld (context 1) 0
 HelloWorld (context 2) 0
-HelloWorld (context 1) 1
-HelloWorld (context 2) 1
+HelloWorld (context 1) 2
+HelloWorld (context 1) 3
 HelloWorld (context 2) 2
 HelloWorld (context 1) 4
-HelloWorld (context 1) 2
+HelloWorld (context 2) 4
+HelloWorld (context 2) 1
+HelloWorld (context 2) 5
+HelloWorld (context 2) 3
+HelloWorld (context 1) 6
 HelloWorld (context 1) 5
-HelloWorld (context 2) 5
-HelloWorld (context 1) 6
-HelloWorld (context 1) 3
-HelloWorld (context 1) 7
 HelloWorld (context 2) 7
 HelloWorld (context 1) 8
+HelloWorld (context 1) 1
 HelloWorld (context 2) 8
+HelloWorld (context 1) 7
+HelloWorld (context 2) 6
+HelloWorld (context 2) 9
 HelloWorld (context 1) 9
-HelloWorld (context 2) 9
-HelloWorld (context 2) 3
-HelloWorld (context 2) 6
-HelloWorld (context 2) 4
-~~~~~
-
-### Conclusion
+~~~~~
+
+### Conclusion ###
 This demonstrates that a single ThimbleExecutor could be used to handle sequential tasks. In situations where tasks for multiple contexts need to be executed in sequence, rather than having a single-thread per context, a single multi-thread ThimbleExecutor can be used.
 
-## Coalescing task demonstration
+## Coalescing task demonstration ##
 
 Now we will look at how a ThimbleExecutor handles coalescing tasks. Coalescing tasks are tasks where a later task can overwrite a previous submitted task that has not executed yet. The code below executes 100 coalescing tasks in a 4-thread ThimbleExecutor.
 
@@ -175,7 +175,7 @@
     {
         Executor executor = new ThimbleExecutor(4);
         final int count = 100;
-        final CountDownLatch latch = new CountDownLatch(count);
+        final CountDownLatch latch = new CountDownLatch(count * 2);
         for (int i = 0; i &lt; count; i++)
         {
             final int myCount = i;
@@ -217,32 +217,32 @@
 }
 ~~~~~
 
-The output shows that not every submitted task is run and always a ;ater task is run (never a former one). Indeed only about 1/10th of the tasks per context are executed. Coalescing tasks are useful in situations where a high-frequency producer is scheduling tasks where logically only the latest task at any point in time needs to be executed. This can drastically improve throughput performance.
+The output shows that not every submitted task is run but it is always a later task that is run (never a former one). Indeed only about 1/10th of the tasks per context are executed. Coalescing tasks are useful in situations where a high-frequency producer is scheduling tasks where logically only the latest task at any point in time needs to be executed. This can drastically improve throughput performance.
 
 ~~~~~
 HelloWorld (context 1) 0
-HelloWorld (context 2) 9
-HelloWorld (context 2) 22
-HelloWorld (context 1) 23
-HelloWorld (context 2) 25
+HelloWorld (context 2) 4
 HelloWorld (context 1) 28
-HelloWorld (context 2) 33
-HelloWorld (context 2) 40
-HelloWorld (context 1) 37
-HelloWorld (context 2) 47
-HelloWorld (context 1) 55
-HelloWorld (context 2) 60
-HelloWorld (context 1) 68
-HelloWorld (context 2) 73
-HelloWorld (context 1) 79
-HelloWorld (context 2) 84
-HelloWorld (context 1) 87
-HelloWorld (context 2) 93
+HelloWorld (context 1) 32
+HelloWorld (context 2) 35
+HelloWorld (context 2) 42
+HelloWorld (context 1) 38
+HelloWorld (context 2) 50
+HelloWorld (context 1) 56
+HelloWorld (context 1) 59
+HelloWorld (context 1) 61
+HelloWorld (context 1) 67
+HelloWorld (context 2) 67
+HelloWorld (context 1) 72
+HelloWorld (context 2) 82
+HelloWorld (context 2) 89
+HelloWorld (context 2) 95
+HelloWorld (context 1) 97
+HelloWorld (context 2) 99
 HelloWorld (context 1) 99
-HelloWorld (context 2) 99
-~~~~~
-
-Compare with using a standard 4-thread exeuctor.
+~~~~~
+
+Compare with using a standard 4-thread executor.
 
 ~~~~~
 :::java
@@ -252,7 +252,7 @@
     {
         Executor executor = Executors.newFixedThreadPool(4);
         final int count = 100;
-        final CountDownLatch latch = new CountDownLatch(count);
+        final CountDownLatch latch = new CountDownLatch(count * 2);
         for (int i = 0; i &lt; count; i++)
         {
             final int myCount = i;
@@ -294,11 +294,10 @@
 }
 ~~~~~
 
-The output shows that every task is run and also not in order (which could be important).
+The output shows that every task is run and also not in order.
 
 ~~~~~
 HelloWorld (context 1) 0
-HelloWorld (context 2) 0
 HelloWorld (context 1) 2
 HelloWorld (context 2) 2
 HelloWorld (context 1) 3
@@ -310,7 +309,6 @@
 HelloWorld (context 1) 6
 HelloWorld (context 2) 6
 ...
-HelloWorld (context 1) 96
 HelloWorld (context 2) 96
 HelloWorld (context 1) 97
 HelloWorld (context 2) 97
@@ -318,9 +316,15 @@
 HelloWorld (context 2) 98
 HelloWorld (context 1) 99
 HelloWorld (context 2) 99
-HelloWorld (context 2) 92
-HelloWorld (context 2) 95
-HelloWorld (context 2) 94
-~~~~~
-
-### Conclusion
+HelloWorld (context 1) 69
+HelloWorld (context 1) 75
+HelloWorld (context 2) 74
+~~~~~
+
+### Conclusion ###
+Executing coalescing tasks using a ThimbleExecutor provides an efficient way of handling fast-producer situations where the data being produced can be coalesced.
+
+## Task statistics
+
+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
+
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ramon Servadei</dc:creator><pubDate>Sun, 09 Dec 2012 16:01:53 -0000</pubDate><guid>https://sourceforge.net47ff10c59155fcae7500ea936c9ea5cfd726790c</guid></item><item><title>WikiPage Tutorial modified by Ramon Servadei</title><link>https://sourceforge.net/p/thimble/wiki/Tutorial/</link><description>&lt;pre&gt;--- v3
+++ v4
@@ -164,3 +164,163 @@
 This demonstrates that a single ThimbleExecutor could be used to handle sequential tasks. In situations where tasks for multiple contexts need to be executed in sequence, rather than having a single-thread per context, a single multi-thread ThimbleExecutor can be used.
 
 ## Coalescing task demonstration
+
+Now we will look at how a ThimbleExecutor handles coalescing tasks. Coalescing tasks are tasks where a later task can overwrite a previous submitted task that has not executed yet. The code below executes 100 coalescing tasks in a 4-thread ThimbleExecutor.
+
+~~~~~
+:::java
+public class TestCoalescing
+{
+    public static void main(String[] args) throws Exception
+    {
+        Executor executor = new ThimbleExecutor(4);
+        final int count = 100;
+        final CountDownLatch latch = new CountDownLatch(count);
+        for (int i = 0; i &lt; count; i++)
+        {
+            final int myCount = i;
+            
+            executor.execute(new ICoalescingRunnable()
+            {
+                @Override
+                public void run()
+                {
+                    System.out.println("HelloWorld (context 1) " + myCount);
+                    latch.countDown();
+                }
+                
+                @Override
+                public Object context()
+                {
+                    return "context1";
+                }
+            });
+            
+            executor.execute(new ICoalescingRunnable()
+            {
+                @Override
+                public void run()
+                {
+                    System.out.println("HelloWorld (context 2) " + myCount);
+                    latch.countDown();
+                }
+                
+                @Override
+                public Object context()
+                {
+                    return "context2";
+                }
+            });
+        }
+        latch.await();        
+    }
+}
+~~~~~
+
+The output shows that not every submitted task is run and always a ;ater task is run (never a former one). Indeed only about 1/10th of the tasks per context are executed. Coalescing tasks are useful in situations where a high-frequency producer is scheduling tasks where logically only the latest task at any point in time needs to be executed. This can drastically improve throughput performance.
+
+~~~~~
+HelloWorld (context 1) 0
+HelloWorld (context 2) 9
+HelloWorld (context 2) 22
+HelloWorld (context 1) 23
+HelloWorld (context 2) 25
+HelloWorld (context 1) 28
+HelloWorld (context 2) 33
+HelloWorld (context 2) 40
+HelloWorld (context 1) 37
+HelloWorld (context 2) 47
+HelloWorld (context 1) 55
+HelloWorld (context 2) 60
+HelloWorld (context 1) 68
+HelloWorld (context 2) 73
+HelloWorld (context 1) 79
+HelloWorld (context 2) 84
+HelloWorld (context 1) 87
+HelloWorld (context 2) 93
+HelloWorld (context 1) 99
+HelloWorld (context 2) 99
+~~~~~
+
+Compare with using a standard 4-thread exeuctor.
+
+~~~~~
+:::java
+public class TestCoalescingWithStandardExecutor
+{
+    public static void main(String[] args) throws Exception
+    {
+        Executor executor = Executors.newFixedThreadPool(4);
+        final int count = 100;
+        final CountDownLatch latch = new CountDownLatch(count);
+        for (int i = 0; i &lt; count; i++)
+        {
+            final int myCount = i;
+            
+            executor.execute(new ICoalescingRunnable()
+            {
+                @Override
+                public void run()
+                {
+                    System.out.println("HelloWorld (context 1) " + myCount);
+                    latch.countDown();
+                }
+                
+                @Override
+                public Object context()
+                {
+                    return "context1";
+                }
+            });
+            
+            executor.execute(new ICoalescingRunnable()
+            {
+                @Override
+                public void run()
+                {
+                    System.out.println("HelloWorld (context 2) " + myCount);
+                    latch.countDown();
+                }
+                
+                @Override
+                public Object context()
+                {
+                    return "context2";
+                }
+            });
+        }
+        latch.await();        
+    }
+}
+~~~~~
+
+The output shows that every task is run and also not in order (which could be important).
+
+~~~~~
+HelloWorld (context 1) 0
+HelloWorld (context 2) 0
+HelloWorld (context 1) 2
+HelloWorld (context 2) 2
+HelloWorld (context 1) 3
+HelloWorld (context 2) 3
+HelloWorld (context 1) 4
+HelloWorld (context 2) 4
+HelloWorld (context 1) 5
+HelloWorld (context 2) 5
+HelloWorld (context 1) 6
+HelloWorld (context 2) 6
+...
+HelloWorld (context 1) 96
+HelloWorld (context 2) 96
+HelloWorld (context 1) 97
+HelloWorld (context 2) 97
+HelloWorld (context 1) 98
+HelloWorld (context 2) 98
+HelloWorld (context 1) 99
+HelloWorld (context 2) 99
+HelloWorld (context 2) 92
+HelloWorld (context 2) 95
+HelloWorld (context 2) 94
+~~~~~
+
+### Conclusion
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ramon Servadei</dc:creator><pubDate>Sun, 09 Dec 2012 15:43:08 -0000</pubDate><guid>https://sourceforge.netc2e105e81659c9aba984d5a098cd5782aa5e6554</guid></item><item><title>WikiPage Tutorial modified by Ramon Servadei</title><link>https://sourceforge.net/p/thimble/wiki/Tutorial/</link><description>&lt;pre&gt;--- v2
+++ v3
@@ -1,10 +1,10 @@
-Thimble "Hello World" Tutorial
-====
+# Thimble "Hello World" Tutorial
 
 This tutorial will take you through all the features of Thimble. 
 
-Sequential task demonstration
-----
+[TOC]
+
+## Sequential task demonstration
 
 This tutorial will demonstrate how a ThimbleExecutor executes sequential tasks. The code below runs a sequential task in a 4-thread ThimbleExecutor.
 
@@ -20,19 +20,36 @@
         for (int i = 0; i &lt; count; i++)
         {
             final int myCount = i;
+            
             executor.execute(new ISequentialRunnable()
             {
                 @Override
                 public void run()
                 {
-                    System.out.println("HelloWorld " + myCount);
+                    System.out.println("HelloWorld (context 1) " + myCount);
                     latch.countDown();
                 }
                 
                 @Override
                 public Object context()
                 {
-                    return "context for this type of task";
+                    return "context1";
+                }
+            });
+            
+            executor.execute(new ISequentialRunnable()
+            {
+                @Override
+                public void run()
+                {
+                    System.out.println("HelloWorld (context 2) " + myCount);
+                    latch.countDown();
+                }
+                
+                @Override
+                public Object context()
+                {
+                    return "context2";
                 }
             });
         }
@@ -41,19 +58,29 @@
 }
 ~~~~~
 
-The output demonstrates that the tasks are executed in order. 
+The output demonstrates that the tasks are executed in order. Notice that there is some inter-leaving for the execution of the sequential tasks between context 1 and context 2 but that both contexts have their tasks executed in sequence.
 
 ~~~~~
-HelloWorld 0
-HelloWorld 1
-HelloWorld 2
-HelloWorld 3
-HelloWorld 4
-HelloWorld 5
-HelloWorld 6
-HelloWorld 7
-HelloWorld 8
-HelloWorld 9
+HelloWorld (context 1) 0
+HelloWorld (context 2) 0
+HelloWorld (context 1) 1
+HelloWorld (context 2) 1
+HelloWorld (context 1) 2
+HelloWorld (context 2) 2
+HelloWorld (context 2) 3
+HelloWorld (context 2) 4
+HelloWorld (context 2) 5
+HelloWorld (context 2) 6
+HelloWorld (context 2) 7
+HelloWorld (context 2) 8
+HelloWorld (context 2) 9
+HelloWorld (context 1) 3
+HelloWorld (context 1) 4
+HelloWorld (context 1) 5
+HelloWorld (context 1) 6
+HelloWorld (context 1) 7
+HelloWorld (context 1) 8
+HelloWorld (context 1) 9
 ~~~~~
 
 Compare this with using a standard multi-thread executor
@@ -70,19 +97,36 @@
         for (int i = 0; i &lt; count; i++)
         {
             final int myCount = i;
+            
             executor.execute(new ISequentialRunnable()
             {
                 @Override
                 public void run()
                 {
-                    System.out.println("HelloWorld " + myCount);
+                    System.out.println("HelloWorld (context 1) " + myCount);
                     latch.countDown();
                 }
                 
                 @Override
                 public Object context()
                 {
-                    return "context for this type of task";
+                    return "context1";
+                }
+            });
+            
+            executor.execute(new ISequentialRunnable()
+            {
+                @Override
+                public void run()
+                {
+                    System.out.println("HelloWorld (context 2) " + myCount);
+                    latch.countDown();
+                }
+                
+                @Override
+                public Object context()
+                {
+                    return "context2";
                 }
             });
         }
@@ -91,22 +135,32 @@
 }
 ~~~~~
 
-The output shows that the tasks are executed non-sequentially (although probably in parallel too).
+The output shows that the tasks are executed non-sequentially.
 
 ~~~~~
-HelloWorld 0
-HelloWorld 3
-HelloWorld 4
-HelloWorld 6
-HelloWorld 7
-HelloWorld 8
-HelloWorld 9
-HelloWorld 1
-HelloWorld 2
-HelloWorld 5
+HelloWorld (context 1) 0
+HelloWorld (context 2) 0
+HelloWorld (context 1) 1
+HelloWorld (context 2) 1
+HelloWorld (context 2) 2
+HelloWorld (context 1) 4
+HelloWorld (context 1) 2
+HelloWorld (context 1) 5
+HelloWorld (context 2) 5
+HelloWorld (context 1) 6
+HelloWorld (context 1) 3
+HelloWorld (context 1) 7
+HelloWorld (context 2) 7
+HelloWorld (context 1) 8
+HelloWorld (context 2) 8
+HelloWorld (context 1) 9
+HelloWorld (context 2) 9
+HelloWorld (context 2) 3
+HelloWorld (context 2) 6
+HelloWorld (context 2) 4
 ~~~~~
 
-This demonstrates that a single ThimbleExecutor could be used to handle both sequential tasks and tasks with no sequential processing requirements.
+### Conclusion
+This demonstrates that a single ThimbleExecutor could be used to handle sequential tasks. In situations where tasks for multiple contexts need to be executed in sequence, rather than having a single-thread per context, a single multi-thread ThimbleExecutor can be used.
 
-Coalescing task demonstration
------
+## Coalescing task demonstration
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ramon Servadei</dc:creator><pubDate>Sun, 09 Dec 2012 15:30:48 -0000</pubDate><guid>https://sourceforge.net79aca5fe8caa8019e844a7d5768b3ff206e39078</guid></item><item><title>WikiPage Tutorial modified by Ramon Servadei</title><link>https://sourceforge.net/p/thimble/wiki/Tutorial/</link><description>&lt;pre&gt;--- v1
+++ v2
@@ -3,10 +3,10 @@
 
 This tutorial will take you through all the features of Thimble. 
 
-Sequential task demo
+Sequential task demonstration
 ----
 
-This tutorial will demonstrate how thimble handles sequential tasks. The code below runs a sequential task in a 4-thread thimble executor.
+This tutorial will demonstrate how a ThimbleExecutor executes sequential tasks. The code below runs a sequential task in a 4-thread ThimbleExecutor.
 
 ~~~~~
 :::java
@@ -25,7 +25,7 @@
                 @Override
                 public void run()
                 {
-                    System.out.println("count=" + myCount);
+                    System.out.println("HelloWorld " + myCount);
                     latch.countDown();
                 }
                 
@@ -41,19 +41,19 @@
 }
 ~~~~~
 
-The output
+The output demonstrates that the tasks are executed in order. 
 
 ~~~~~
-count=0
-count=1
-count=2
-count=3
-count=4
-count=5
-count=6
-count=7
-count=8
-count=9
+HelloWorld 0
+HelloWorld 1
+HelloWorld 2
+HelloWorld 3
+HelloWorld 4
+HelloWorld 5
+HelloWorld 6
+HelloWorld 7
+HelloWorld 8
+HelloWorld 9
 ~~~~~
 
 Compare this with using a standard multi-thread executor
@@ -75,7 +75,7 @@
                 @Override
                 public void run()
                 {
-                    System.out.println("count=" + myCount);
+                    System.out.println("HelloWorld " + myCount);
                     latch.countDown();
                 }
                 
@@ -91,17 +91,22 @@
 }
 ~~~~~
 
-The output is
+The output shows that the tasks are executed non-sequentially (although probably in parallel too).
 
 ~~~~~
-count=1
-count=4
-count=5
-count=6
-count=7
-count=8
-count=9
-count=3
-count=2
-count=0
+HelloWorld 0
+HelloWorld 3
+HelloWorld 4
+HelloWorld 6
+HelloWorld 7
+HelloWorld 8
+HelloWorld 9
+HelloWorld 1
+HelloWorld 2
+HelloWorld 5
 ~~~~~
+
+This demonstrates that a single ThimbleExecutor could be used to handle both sequential tasks and tasks with no sequential processing requirements.
+
+Coalescing task demonstration
+-----
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ramon Servadei</dc:creator><pubDate>Sun, 09 Dec 2012 15:22:10 -0000</pubDate><guid>https://sourceforge.net88abb542fdf345548074821271dabf7f357d237d</guid></item><item><title>WikiPage Tutorial modified by Ramon Servadei</title><link>https://sourceforge.net/p/thimble/wiki/Tutorial/</link><description>Thimble "Hello World" Tutorial
====

This tutorial will take you through all the features of Thimble. 

Sequential task demo
----

This tutorial will demonstrate how thimble handles sequential tasks. The code below runs a sequential task in a 4-thread thimble executor.

~~~~~
:::java
public class TestSequential
{
    public static void main(String[] args) throws Exception
    {
        Executor executor = new ThimbleExecutor(4);
        final int count = 10;
        final CountDownLatch latch = new CountDownLatch(count);
        for (int i = 0; i &lt; count; i++)
        {
            final int myCount = i;
            executor.execute(new ISequentialRunnable()
            {
                @Override
                public void run()
                {
                    System.out.println("count=" + myCount);
                    latch.countDown();
                }
                
                @Override
                public Object context()
                {
                    return "context for this type of task";
                }
            });
        }
        latch.await();        
    }
}
~~~~~

The output

~~~~~
count=0
count=1
count=2
count=3
count=4
count=5
count=6
count=7
count=8
count=9
~~~~~

Compare this with using a standard multi-thread executor

~~~~~
:::java
public class TestSequentialWithStandardExecutor
{
    public static void main(String[] args) throws Exception
    {
        Executor executor = Executors.newFixedThreadPool(4);
        final int count = 10;
        final CountDownLatch latch = new CountDownLatch(count);
        for (int i = 0; i &lt; count; i++)
        {
            final int myCount = i;
            executor.execute(new ISequentialRunnable()
            {
                @Override
                public void run()
                {
                    System.out.println("count=" + myCount);
                    latch.countDown();
                }
                
                @Override
                public Object context()
                {
                    return "context for this type of task";
                }
            });
        }
        latch.await();        
    }
}
~~~~~

The output is

~~~~~
count=1
count=4
count=5
count=6
count=7
count=8
count=9
count=3
count=2
count=0
~~~~~</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ramon Servadei</dc:creator><pubDate>Sun, 09 Dec 2012 15:15:50 -0000</pubDate><guid>https://sourceforge.net8538fbacac6db79d43e11fd4ba93bbbc76f4dda2</guid></item></channel></rss>