gpt4 book ai didi

java - 提交给ExecutorService对象的任务执行顺序是怎样的?

转载 作者:行者123 更新时间:2023-12-02 09:13:36 25 4
gpt4 key购买 nike

提交给ExecutorService对象的任务执行顺序是怎样的?

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

此外,有什么方法可以指定它的执行顺序。

示例:

ExecutorService executor = Executors.newFixedThreadPool(5);
for(int i =0; i < 100; i++){
executor.submit(() -> {
System.out.println("print task");
})
}

最佳答案

这取决于线程池和队列的实现。

对于 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. 线程1:可运行任务=queue.take()
  2. 线程2:可运行任务=queue.take()
  3. 线程2:task.run();
  4. 线程 1:task.run();

瞧,第二个任务在队列中排在后面,但在第一个任务之前执行。在实践中,这种情况经常发生。

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

关于java - 提交给ExecutorService对象的任务执行顺序是怎样的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59188242/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com