简体   繁体   中英

Why tasks in Threadpool are not executed following FIFO, Java

I know if queue is full the new task will be executed by a newly created thread in priority according to How to guarantee FIFO execution order in a ThreadPoolExecutor

But I have following test code snippets which min core size = max core size.

public class ThreadPoolFifoTest {
    public static void main(String[] args) throws InterruptedException {
        Executor ex = Executors.newFixedThreadPool(10);
        final List<Integer> l = new LinkedList<Integer>();
        final ReentrantLock lock = new ReentrantLock(true);//fair lock
        for(int i=0;i<10000;i++){
            final int num = i ;
            ex.execute(new Runnable() {//FIFO submit 
                @Override
                public void run() {
                    //here since queue is FIFO, it is easy to consider that somebody should be take the task FIFO and let the thread to run this task
                    //so it easy to consider that this should be fifo to go to here. 
                    //But as a result , it is not.
                    lock.lock();
                    l.add(num);
                    lock.unlock();                 
                }
            });
        }

        Thread.sleep(1000);
        System.out.println(l);
        List<Integer> sortedList= new LinkedList<Integer>(l);
        Collections.sort(sortedList);
        System.out.println(sortedList);
        System.out.println(l.equals(sortedList));//not equals here

    }
}

output:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 9, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 84, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
false

Since Queue under the thread pool is FIFO, the task should be poll FIFO and run in the thread, so since I am submiting task folloing order 0.1.2.3.4.....999, my l should looks like sorted, but from the output, it is not, doesn't this mean that the execution order is not FIFO? Why not?

What if I need the task to be executed FIFO?

The problem is that thread only take message off in order, but run independently (as threads should) If you want execution in FIFO you should either

  • use a single thread as you can't run tasks in parallel anyway.
  • use multiple thread but collect the results in the order they were created (not the order they were executed. This is what parallelStream does.

For example

List<Result> results = IntStream.range(0, 10000).parallel()
                                .mapToObject(i -> func(i))
                                .collect(Collector.toList());

This will allow concurrent execution, however the results appear in the original order.

BTW When you sort a LinkedList, it has to turn it into array, sort it and copy it back into the linked list. I suggest using an ArrayList which can be sorted in place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM