我有一个 ReentrantLock,一堆操作正在锁定它,它是使用 new ReentrantLock(true)
公平创建的。有没有办法让线程“闯入”锁并在锁释放后但在任何其他线程之前获取它?
我考虑过定时和不定时tryLock
的各种组合:
tryLock()
如果锁已解锁且线程正在等待,则它本身会闯入锁,但不会等待锁变得可用。- 同样的方法加上超时是公平的。
- 将两者结合起来是行不通的,因为如果一开始就锁定了,基于超时的 tryLock 将回退到公平调度。
还是我错了?
最佳答案
如您所见here ,ReentrantLock
使用 AbstractQueuedSynchronizer
作为实际的线程队列实现。看到它的方法都不是可重写的,您不能轻松地做到这一点,即将标准线程队列替换为优先级队列。
但正如文档中所述:“此类在一定程度上通过将其使用范围专门化为可以依赖于 int 状态、获取和释放参数以及内部 FIFO 等待队列的同步器,为同步提供了高效且可扩展的基础。当这还不够时,您可以使用原子类、您自己的自定义 java.util.Queue 类和 LockSupport 阻塞支持从较低级别构建同步器。”
这就是您需要做的:构建您自己的锁。您的主要目标是让 release
方法使用优先级队列来做出决定。如果性能不是问题,您可以使用标准 PriorityQueue您可以使用 synchronized
、ReentrantLock
或任何其他可用的标准锁使其读写线程安全。线程安全的优先级队列很难获得。但是,如果性能很重要,this paper您可能会对 2003 年以来的内容感兴趣。
但是,由于用户可以在任何给定时间修改线程的优先级,因此仅使用基本队列并使用 stable sort 可能是最简单的。 (为了不弄乱具有相同优先级的线程的顺序)在得到下一个家伙之前。当然,如果您想将其用于高争用的关键部分,性能会很差。
关于java - 优先获取可能被锁定的公平 ReentrantLock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20340230/