簡體   English   中英

為什么線程池中的任務沒有按照 FIFO、Java 執行

[英]Why tasks in Threadpool are not executed following FIFO, Java

我知道如果隊列已滿,新任務將根據如何保證 ThreadPoolExecutor 中的 FIFO 執行順序由新創建的線程優先執行

但是我有以下測試代碼片段,其中最小核心大小 = 最大核心大小。

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

    }
}

輸出:

[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

由於線程池下的隊列是先進先出,任務應該是輪詢先進先出並在線程中運行,所以由於我提交的任務是按照0.1.2.3.4.....999的順序,我的l看起來應該是有序的,但是從輸出,不是,這不是說執行順序不是FIFO嗎? 為什么不?

如果我需要 FIFO 執行任務怎么辦?

問題是線程只按順序關閉消息,但獨立運行(線程應該)如果你想在 FIFO 中執行,你應該

  • 使用單個線程,因為無論如何您都無法並行運行任務。
  • 使用多個線程,但按創建順序(而不是執行順序)收集結果。這就是 parallelStream 所做的。

例如

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

這將允許並發執行,但結果以原始順序出現。

順便說一句,當您對 LinkedList 進行排序時,它必須將其轉換為數組,對其進行排序並將其復制回鏈表中。 我建議使用可以就地排序的 ArrayList。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM