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 < 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 < 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
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.