1

我有一个 ReentrantLock,一堆操作正在锁定,它是用new ReentrantLock(true). 有没有办法让线程“闯入”锁并在释放之后但在任何其他线程之前获取它?

我考虑了 timed 和 untimed 的各种组合tryLock

  • tryLock()如果它已经解锁并且线程正在等待,它本身将插入锁,但不会等待锁变得可用。
  • 与超时相同的方法是公平的。
  • 将两者结合起来是行不通的,因为如果它在开始时被锁定,基于超时的 tryLock 将退回到公平调度。

还是我错了?

4

1 回答 1

1

正如您在此处看到的,ReentrantLock用作AbstractQueuedSynchronizer实际的线程队列实现。看到没有一个方法是可覆盖的,你不能轻易做到这一点,即用优先级队列替换标准线程队列

但正如它在文档中所说:“这个类为同步提供了一个高效和可扩展的基础,部分是通过将它的使用范围专门用于可以依赖 int 状态、获取和释放参数以及内部 FIFO 等待队列的同步器。当这还不够,您可以使用原子类、您自己的自定义 java.util.Queue 类和 LockSupport 阻塞支持从较低级别构建同步器。”

所以这就是你需要做的:建立你自己的锁。您的主要目标是让该release方法使用优先级队列来做出决定。如果性能不是问题,您可以只使用标准PriorityQueuesynchronized,您可以使用ReentrantLock或任何其他可用的标准锁使其读写线程安全。线程安全的优先级队列很难获得。但是,如果性能很重要,您可能会对 2003 年的这篇论文感兴趣。

但是,由于用户可以在任何给定时间修改线程的优先级,因此在获得下一个人之前,使用基本队列并使用稳定排序(以免弄乱具有相同优先级的线程的顺序)可能是最简单的。当然,如果你想将它用于高争用的关键部分,性能会很差。

于 2013-12-03T00:31:13.463 回答