带超时的队列锁及复合锁算法解析
1. 带超时的队列锁(TOLock)
1.1 背景与问题
在多线程编程中,Java 的 Lock
接口提供了 tryLock()
方法,允许调用者指定一个超时时间,表示调用者愿意等待获取锁的最大时长。如果在超时时间内未能获取到锁,尝试将被放弃,方法会返回一个布尔值来指示锁获取是否成功。
对于 BackoffLock
,放弃请求很简单,线程可以直接从 tryLock()
调用中返回,且超时操作是无等待的,只需常数级的步骤。然而,对于队列锁算法,实现超时机制就不那么容易了。如果一个线程直接返回,排在它后面的线程可能会陷入饥饿状态。
1.2 TOLock 算法原理
TOLock 是基于 CLHLock 实现的队列锁,支持无等待超时,即使是位于等待锁的节点列表中间的线程也能实现。
节点状态
- 当
QNode
的pred
字段为null
时,关联的线程要么还未获取到锁,要么还未释放锁。 - 当
QNode
的pred
字段指向一个特殊的静态QNode
对象AVAILABLE
时,关联的线程已经释放了锁。 - 如果
pred
字段指向其他Q