Java 提交给ExecutorService对象的任务的执行顺序是什么?

Java 提交给ExecutorService对象的任务的执行顺序是什么?,java,executorservice,executor,Java,Executorservice,Executor,提交给ExecutorService对象的任务的执行顺序是什么 场景:让我们暂时假设Executor线程池大小为5,我已经向它提交了20个可运行任务,我们知道一次只能执行5个任务,其余任务将在bucket中等待。所以我的问题是提交的任务以什么顺序执行。它是遵循FIFO数据结构还是从bucket中随机选取任务 还有,是否有任何方法可以指定它的执行顺序 例如: ExecutorService executor = Executors.newFixedThreadPool(5); for(int i

提交给ExecutorService对象的任务的执行顺序是什么

场景:让我们暂时假设Executor线程池大小为5,我已经向它提交了20个可运行任务,我们知道一次只能执行5个任务,其余任务将在bucket中等待。所以我的问题是提交的任务以什么顺序执行。它是遵循FIFO数据结构还是从bucket中随机选取任务

还有,是否有任何方法可以指定它的执行顺序

例如:

ExecutorService executor = Executors.newFixedThreadPool(5);
for(int i =0; i < 100; i++){
  executor.submit(() -> {
    System.out.println("print task");
  })
}
ExecutorService executor=Executors.newFixedThreadPool(5);
对于(int i=0;i<100;i++){
执行人提交(()->{
System.out.println(“打印任务”);
})
}

它使用LinkedBlockingQueue存储挂起的任务。因此,对于挂起的任务,它遵循FIFO顺序。请查找java文档以及方法签名

/**
     * Creates a thread pool that reuses a fixed number of threads
     * operating off a shared unbounded queue.  At any point, at most
     * {@code nThreads} threads will be active processing tasks.
     * If additional tasks are submitted when all threads are active,
     * they will wait in the queue until a thread is available.
     * If any thread terminates due to a failure during execution
     * prior to shutdown, a new one will take its place if needed to
     * execute subsequent tasks.  The threads in the pool will exist
     * until it is explicitly {@link ExecutorService#shutdown shutdown}.
     *
     * @param nThreads the number of threads in the pool
     * @return the newly created thread pool
     * @throws IllegalArgumentException if {@code nThreads <= 0}
     */

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
/**
*创建重用固定数量线程的线程池
*在共享无边界队列上运行。在任何时候,最多
*{@code nThreads}线程将是活动的处理任务。
*如果在所有线程都处于活动状态时提交其他任务,
*他们将在队列中等待,直到线程可用。
*如果任何线程在执行过程中由于故障而终止
*在停堆之前,如果需要,将更换一个新的
*执行后续任务。池中的线程将存在
*直到它显式地{@linkexecutorservice#shutdown}。
*
*@param读取池中的线程数
*@返回新创建的线程池

*@throws-IllegalArgumentException如果{@code-nThreads它取决于线程池和队列的实现

对于ThreadPoolExecutor,队列几乎总是SynchronousQueue、LinkedBlockingQueue或ArrayBlockingQueue。 ArrayBlockingQueue和LinkedBlockingQueue保证了FIFO排序。对于SynchronousQueue,这取决于同步机制的FIFO能力,因为SynchronousQueue一次只能保留一个元素。 你最好假设这不是保证

对于ScheduledThreadPoolExecutor,队列是一个DelayQueue。 基本上,它是一个优先级队列,很可能是使用堆数据结构实现的。任务将按照延迟的顺序从队列中获取,但对于具有相同延迟的两个任务,不能保证FIFO

但是,你必须考虑到,从队列中挑选任务并不意味着它将被立即执行,因为线程的前导特性。执行器的主循环看起来基本上类似于:

public void run () {
    while(!terminated) {
        Runnable task = queue.take();
        task.run();
    }
}
假设有两个线程正在运行此代码。这种情况可能发生:

  • 线程1:
    Runnable task=queue.take()
  • 线程2:
    Runnable task=queue.take()
  • 线程2:
    task.run();
  • 线程1:
    task.run();
  • 瞧,第二个任务在队列中排在后面,但在第一个任务之前执行。实际上,这种情况经常发生


    最后,你不能也不应该假设任何事情。

    拥有一个日志并测试它你可以读取文档。ThreadpoolExecutor使用blockingQueue来保存尚未运行的任务。如果你愿意,你可以传入PriorityBlockingQueue。这回答了你的问题吗?这就是我要找的。谢谢dassum