priorityblockingqueue 是基于堆的无界线程安全优先队列,依赖 comparable 或 comparator 排序,不保证遍历有序,不允许 null 元素,相等元素出队顺序不确定。

PriorityBlockingQueue 是 Java 中基于堆实现的无界线程安全优先队列,它**不依赖 synchronized 或显式锁来保证排序**,而是依靠元素自身的 Comparable 实现(或构造时传入的 Comparator)来决定元素的优先级顺序。
Comparable 接口定义自然排序规则
当元素类型实现了 Comparable 接口(如 String、Integer、BigDecimal 等),PriorityBlockingQueue 会调用其 compareTo() 方法比较大小。默认按“升序”逻辑建堆——即 compareTo() 返回负数的元素优先级更高(更早出队)。这和“数值小优先”一致,但本质是:堆顶始终是 compareTo 结果最小的元素。
- 例如:Integer 实现了 Comparable,
3.compareTo(5)返回 -2 → 3 优先级高于 5 → 3 先出队 - 自定义类必须正确实现
compareTo(),否则可能抛ClassCastException或排序异常 - 若元素未实现 Comparable,且未提供 Comparator,插入时会立即抛
ClassCastException
PriorityBlockingQueue 不保证完全有序遍历
虽然出队严格遵循优先级(每次 poll() 返回当前最高优先级元素),但 内部存储不维持全局有序。调用 iterator() 或 toArray() 得到的顺序是堆的层次遍历结果,不是升序/降序排列。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 不能靠 for-each 遍历获取“已排序列表”
- 若需完整有序序列,应反复
poll(),或先转为 List 后调用Collections.sort() - 多线程环境下,迭代器不反映实时排序状态,也不支持并发修改
Comparator 优先级高于 Comparable
构造 PriorityBlockingQueue 时若传入 Comparator,则忽略元素自身的 Comparable 实现,统一按该 Comparator 的 compare() 规则排序。
- 例如:
new PriorityBlockingQueue(11, Collections.reverseOrder())实现最大堆(大数优先) - Comparator 和 Comparable 可以共存,但队列只用其中一个——有 Comparator 就不用 Comparable
- Comparator 为 null 且元素不可比较时,运行时报错,不会静默降级
注意 null 值与相等元素的处理
PriorityBlockingQueue 不允许 null 元素,插入 null 会直接抛 NullPointerException。对于 compareTo 返回 0 的相等元素,队列不做额外稳定排序保证——相同优先级的元素出队顺序不确定(取决于插入时机和堆调整路径)。
- 不要依赖“插入先后”决定相同优先级元素的出队顺序
- 若需稳定排序,可在 compareTo 中加入插入序号作为第二排序键
- 所有元素必须能相互比较:A.compareTo(B) 和 B.compareTo(A) 应符号相反,且满足自反性、传递性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










