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