java - 优先获取可能被锁定的公平 ReentrantLock

标签 java multithreading concurrency locking reentrantlock

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

我考虑过定时和不定时tryLock的各种组合:

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

还是我错了?

最佳答案

如您所见hereReentrantLock 使用 AbstractQueuedSynchronizer作为实际的线程队列实现。看到它的方法都不是可重写的,您不能轻松地做到这一点,即将标准线程队列替换为优先级队列

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

这就是您需要做的:构建您自己的锁。您的主要目标是让 release 方法使用优先级队列来做出决定。如果性能不是问题,您可以使用标准 PriorityQueue您可以使用 synchronizedReentrantLock 或任何其他可用的标准锁使其读写线程安全。线程安全的优先级队列很难获得。但是,如果性能很重要,this paper您可能会对 2003 年以来的内容感兴趣。

但是,由于用户可以在任何给定时间修改线程的优先级,因此仅使用基本队列并使用 stable sort 可能是最简单的。 (为了不弄乱具有相同优先级的线程的顺序)在得到下一个家伙之前。当然,如果您想将其用于高争用的关键部分,性能会很差。

关于java - 优先获取可能被锁定的公平 ReentrantLock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20340230/

相关文章:

java - 具有未定义迭代次数的循环

c# - 使用两个参数来线程化子进程?

multithreading - 我不明白信号量和锁之间的区别

java - 为什么 EclEmma 不涵盖 syncronized(MyClass.class)?

java - 检查定期 ScheduledFuture 是否正在运行

java - 提高基于正则表达式的替换性能

java - Props(new A with B) 和 Props[A with B] 之间的区别

java - 通过 Spring Boot 应用程序关闭 Tomcat 日志记录

java - 使用 JNI、多线程从 Fortran 调用 Java

c# - 同时存在 Oracle 连接和 TCP 客户端/服务器连接