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