MST

星途 面试题库

面试题:Java线程池阻塞队列对任务执行顺序的影响

在Java线程池中,不同类型的阻塞队列(如ArrayBlockingQueue、LinkedBlockingQueue等)对任务的执行顺序会产生怎样不同的影响?如果要实现按照任务优先级执行,应该如何选择和配置阻塞队列?
21.1万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 不同类型阻塞队列对任务执行顺序的影响
    • ArrayBlockingQueue
      • 它是一个有界的阻塞队列,基于数组实现。当线程池从该队列取任务时,遵循FIFO(先进先出)原则。这意味着先进入队列的任务会先被取出执行,在没有其他干扰的情况下,任务的执行顺序和提交顺序一致。
    • LinkedBlockingQueue
      • 它可以是有界或无界的(默认是无界),基于链表实现。同样遵循FIFO原则,先提交到队列的任务会先被取出执行,任务执行顺序和提交顺序基本一致。不过,由于其基于链表,在高并发场景下,添加和移除元素的性能相对稳定,不像ArrayBlockingQueue基于数组可能在扩容等操作时存在性能波动。
  2. 实现按照任务优先级执行
    • 选择PriorityBlockingQueue
      • PriorityBlockingQueue是一个无界的阻塞队列,它会根据任务的自然顺序(如果任务实现了Comparable接口)或者根据构造队列时传入的Comparator来对任务进行排序。在从队列取任务时,会优先取出优先级最高的任务,这样就能实现按照任务优先级执行。
    • 配置
      • 自定义任务类需要实现Comparable接口,重写compareTo方法来定义任务的优先级比较逻辑。例如:
class PriorityTask implements Comparable<PriorityTask>{
    private int priority;
    // 其他任务相关属性和方法

    public PriorityTask(int priority) {
        this.priority = priority;
    }

    @Override
    public int compareTo(PriorityTask o) {
        return Integer.compare(this.priority, o.priority);
    }
}
 - 在创建线程池时,使用`PriorityBlockingQueue`作为阻塞队列:
ExecutorService executorService = new ThreadPoolExecutor(
        corePoolSize,
        maximumPoolSize,
        keepAliveTime,
        TimeUnit.SECONDS,
        new PriorityBlockingQueue<>());

这样,提交到线程池的PriorityTask任务就会按照优先级顺序执行。