为什么在FIFO,Java之后不执行Threadpool中的任务 [英] Why tasks in Threadpool are not executed following FIFO, Java

查看:109
本文介绍了为什么在FIFO,Java之后不执行Threadpool中的任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如果队列已满,新任务将由新创建的线程按优先级执行如何保证ThreadPoolExecutor中的FIFO执行顺序

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

    }
}

输出:

[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

Sin ce线程池下的队列是FIFO,任务应该是轮询FIFO并在线程中运行,所以因为我提交任务后续命令0.1.2.3.4 ..... 999,我的 l 应该看起来像排序,但是从输出来看,它不是,这是不是意味着执行顺序不是FIFO?为什么不?

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?

如果我需要执行FIFO任务怎么办?

What if I need the task to be executed FIFO?

推荐答案

问题是线程只按顺序关闭消息,但是独立运行(如线程所示)如果你想在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


  • 使用单个线程,因为无论如何都无法并行运行任务。

  • 使用多个线程,但按照创建顺序收集结果(而不是执行它们的顺序。是parallelStream的作用。

例如

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当您对LinkedList进行排序时,必须将其转换为数组,对其进行排序将其复制回链表。我建议使用可以按顺序排序的ArrayList。

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.

这篇关于为什么在FIFO,Java之后不执行Threadpool中的任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆