[concurrency-interest] Execution Priority

Tim Peierls tim at peierls.net
Thu Jul 7 16:44:18 EDT 2005


The whole point of a thread pool is to run tasks independently, so that 
newly submitted tasks don't have to wait for other tasks to finish before 
running.

ThreadPoolExecutor's internal queue, which is normally FIFO, is only used 
to keep track of tasks that have not yet run because there was no worker 
thread available to run them when they were submitted. In your case, five 
threads are available, and there are five tasks, so the tasks never have to 
wait on the queue for a worker thread to free up.

So there is no particular order in which these tasks should execute their 
print statements. When I run your code I get two kinds of results:

  Starting task Task 0 at 16:21:10:421
  Starting task Task 1 at 16:21:10:421
  Starting task Task 3 at 16:21:10:421
  Starting task Task 4 at 16:21:10:421
  Starting task Task 2 at 16:21:10:421
  Ending task Task 0 at 16:21:10:421 after 0 milliseconds
  Ending task Task 1 at 16:21:10:421 after 0 milliseconds
  Ending task Task 4 at 16:21:10:421 after 0 milliseconds
  Ending task Task 2 at 16:21:10:437 after 16 milliseconds
  Ending task Task 3 at 16:21:10:437 after 16 milliseconds

and

  Starting task Task 2 at 16:28:48:250
  Ending task Task 2 at 16:28:48:265 after 15 milliseconds
  Starting task Task 4 at 16:28:48:281
  Ending task Task 4 at 16:28:48:281 after 0 milliseconds
  Starting task Task 3 at 16:28:48:281
  Ending task Task 3 at 16:28:48:281 after 0 milliseconds
  Starting task Task 1 at 16:28:48:281
  Ending task Task 1 at 16:28:48:281 after 0 milliseconds
  Starting task Task 0 at 16:28:48:281
  Ending task Task 0 at 16:28:48:281 after 0 milliseconds

But that's just my computer. *Any* ordering and interleaving of the tasks 
(where each task's start message precedes its end message) is theoretically 
possible.

Note that if you use a single thread executor, then you *do* get the FIFO 
ordering you were expecting.

     service = Executors.newSingleThreadExecutor();

--tim


Fon Francis Tran wrote:
> Hello,
> 
>   I tried to test the ThreadPoolExecutor with a simple program but found 
> that the runnable jobs
>   are not executed as FIFO (Using LinkedBlockingQueue) as I would 
> expected when the
>   corePoolSize is not 1. 
> 
>   The result and the code are listed below. I would guess the task 
> should be executed from
>   0 to 4 but they seem to be executed  at random.  Anyone knows why?
> 
>   Many thanks,
> 
> Fon
> 
> 
>    Result:
> 
> Starting task Task 4 at 04:39:29:179
> Ending task Task 4 at 04:39:29:190 after 11 milliseconds
> Starting task Task 1 at 04:39:29:200
> Ending task Task 1 at 04:39:29:202 after 2 milliseconds
> Starting task Task 2 at 04:39:29:207
> Ending task Task 2 at 04:39:29:208 after 1 milliseconds
> Starting task Task 3 at 04:39:29:211
> Ending task Task 3 at 04:39:29:216 after 5 milliseconds
> Starting task Task 0 at 04:39:29:219
> Ending task Task 0 at 04:39:29:221 after 2 milliseconds
> Process terminated with exit code 0
> 
>    Code:
> 
> import edu.emory.mathcs.backport.java.util.concurrent.*;
> import java.util.*;
> import java.text.*;
> 
> public class TestConcurrent {
>   public static void main(String[] args) {
>     int nTasks = 5;
>     int fib = 4;
> 
>     ExecutorServiceAccess esa = new ExecutorServiceAccess();
>     for (int i = 0; i < nTasks; i++)
>         esa.excute(new Task2(fib, "Task " + i));
>       esa.shutdown();
>     }
> }
> 
> class ExecutorServiceAccess {
>     private ExecutorService service;
> 
>     public ExecutorServiceAccess () {
>         service = Executors.newFixedThreadPool(5);
>     }
>     public void excute(Runnable r) {
>         service.execute(r);
>     }
>     public void shutdown() {
>         service.shutdown();
>     }
> }
> 
> class Task2 implements Runnable {
>   long n;
>   String id;
> 
>   private long doSomething(long n) {
>     return n*n-n;
>   }
>   public Task2(long n, String id) {
>     this.n = n;
>     this.id = id;
>   }
>   public void run() {
>     DateFormat df = new SimpleDateFormat("HH:mm:ss:SSS");
>     long startTime = System.currentTimeMillis();
>     System.out.println("Starting task " + id + " at " + df.format(new 
> Date()));
>     doSomething(n);
>     long endTime = System.currentTimeMillis();
>     System.out.println("Ending task " + id + " at " + df.format(new Date())
>         + " after " + (endTime - startTime) + " milliseconds");
>   }
> }
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at altair.cs.oswego.edu
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest




More information about the Concurrency-interest mailing list