aqs 的 state 不能用于编码优先级,因其仅支持原子、可预测的标量语义,拆分位会破坏 compareandsetstate 等原子操作的可靠性,并干扰共享锁等协议中负/零/正数的语义约定。

state 是 AQS 的核心整型状态变量,但**它本身不支持优先级语义**——AQS 的 FIFO 队列天然按入队顺序调度,state 仅用于表示资源数量、锁持有状态等标量信息。想靠位运算在 state 上“编码优先级”,会直接破坏 AQS 对 state 的原子性操作约定(如 compareAndSetState),导致竞争逻辑不可靠。
为什么不能用 state 低/高位存优先级
AQS 要求 state 的修改必须是原子、可预测、可回滚的。比如 tryAcquireShared 返回负数表示失败、0 表示刚好耗尽、正数表示剩余许可数——这是共享锁协议的基础。若把 state 拆成 (count :
- 多个线程并发 CAS 修改
state时,会因优先级字段干扰导致 count 更新丢失(ABA 变形) -
acquireShared内部依赖tryAcquireShared的返回值做分支判断,位编码后无法直接参与许可数计算 - 唤醒逻辑(
doReleaseShared)只遍历队列,不读取state做调度决策,优先级字段完全无用
真正可行的优先级调度必须改队列节点行为
AQS 允许你自定义 Node 的排队逻辑,这才是插入优先级的唯一安全位置:
- 继承
AbstractQueuedSynchronizer,重写addWaiter方法,在构造Node时注入优先级字段(如int priority) - 重写
acquireQueued中的shouldParkAfterFailedAcquire判断逻辑,让高优先级节点跳过低优先级前驱,实现“插队”(需配合unparkSuccessor改写) - 注意:这会破坏 FIFO,必须同步修改
cancelAcquire和fullyRelease,避免节点状态错乱 - JDK 自带的
PriorityBlockingQueue不适用于 AQS 队列,因为 AQS 队列是双向链表且强耦合park/unpark语义
更务实的替代方案:用两个 AQS 实例分层控制
不硬改 AQS 底层,而是用组合方式模拟优先级效果:
- 维护一个高优先级专用 AQS(
highPriorityAqs)和一个普通 AQS(normalAqs) - 调用方先尝试
highPriorityAqs.tryAcquireShared(1),成功则走高优路径;失败再退到normalAqs.acquireShared(1) - 释放时需明确调用对应 AQS 的
tryReleaseShared,避免状态泄漏 - 优势:零侵入 AQS,兼容所有 JDK 版本;劣势:无法做到“同一队列内动态升降级”
真正的优先级共享锁不是靠 state 位运算能解决的,它本质是调度策略问题。AQS 提供的是排队基础设施,不是调度器——你要替换的是“怎么排”,而不是“怎么记”。










