java - StampedLock 如何排队锁定请求?

标签 java multithreading concurrency locking

我正在调查基于 Java8 的 StampedLock ( javadoc here ) 锁定缓存,但我无法在网上找到令人信服的实现,尽管阅读了文章喜欢StampedLock Idioms .

在对 ReentrantReadWriteLock 不允许将读锁升级为写锁感到震惊之后,我对 Java 的多线程和并发产品感觉不太乐观,其次是难以归位在信誉良好的替代解决方案上。

我的问题是,没有明确的声明可以消除我对 StampedLock 会在有读取请求排队时无限期地阻止写入请求的担忧。

查看文档,有 2 条评论引起了我的怀疑。

来自Javadoc :

The scheduling policy of StampedLock does not consistently prefer readers over writers or vice versa. All "try" methods are best-effort and do not necessarily conform to any scheduling or fairness policy.

来自source code :

 * These rules apply to threads actually queued. All tryLock forms
 * opportunistically try to acquire locks regardless of preference
 * rules, and so may "barge" their way in.  Randomized spinning is
 * used in the acquire methods to reduce (increasingly expensive)
 * context switching while also ....

所以它暗示了一个读写锁队列,但我需要阅读并消化全部 1500 行源代码才能确定它。

我认为它一定在那里,因为我发现了一个 good benchmarking article这表明 StampedLock 是实现多读/少写的方法。但是,由于缺乏在线报道,我仍然很担心。

从根本上说,我想我希望实现一个可以在 javadoc 之后即插即用的实现,但最后我只能在网上搜索,想知道为什么在任何地方都没有循环 StampedLock 的示例#tryOptimisticRead() - 即使是 code from the benchmark article不那样做。

Java 并发这么难还是我错过了一些明显的东西?

最佳答案

"Is Java concurrency this difficult or have I missed something obvious?"

Java 并发是否比(比如说)C++ 或 Python 并发更难,这是一个意见问题1

但是,是的,在任何允许不同线程直接更新共享数据结构的语言中,并发都是困难的2。 (仅)支持类 CSP 并发的语言更容易理解和推理。

引用:


就您关于公平性的观点而言,Java 中的大多数锁定形式确实不能保证公平性。事实上,许多与线程调度有关的事情都是(有意地)松散地指定的。但是编写避免这些问题的代码并不难……一旦您了解了这些库以及如何使用它们。


关于您关于 StampedLock 行为的具体问题。

My issue is that there's no definitive statement to allay my fears that StampedLock will block write requests indefinitely while there are read requests queued.

没有这样的声明3 因为这样的行为是可能的。它源于对 StampedLock API 文档的仔细阅读。例如,它说:

"The scheduling policy of StampedLock does not consistently prefer readers over writers or vice versa."

简而言之,没有任何东西可以保证未定时的 writeLock 最终会获得锁。

如果需要断然避免读者导致写者饥饿的场景,那么就不要使用writeLockreadLock。您可以使用 tryOptimisticRead 而不是 readLock。或者您可以设计和实现不同的同步机制。


最后,您似乎在暗示 StampedLock 应该 提供一种直接处理您的场景的方法和/或文档应该专门向非专家用户解释如何处理。我提请人们注意这一点:

"StampedLocks are designed for use as internal utilities in the development of thread-safe components.".

您很难找到相关示例的事实并不是 javadoc 的错。如果有的话,它支持此 API 适用于专家的推断......


1 - 我认为 Java 的并发支持至少比大多数其他同类语言更容易理解。 Java 内存模型(JLS 的第 17.4 章)详细说明,Goetz 等人的“Java Concurrency In Practice”很好地解释了并发编程的来龙去脉。
2 - ....对于大多数程序员。
3 - 如果这对您来说还不够明确,请给自己写一个示例,其中有一个(模拟的)无限大的读取请求序列和多个读取器线程。运行它并查看写入线程是否停止,直到读取请求全部耗尽。

关于java - StampedLock 如何排队锁定请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50155611/

相关文章:

java - 系统找不到指定的文件

java - 在 AWT (Java) 中排序和显示数组的问题

c++ - unixaccept()函数两次返回相同的文件描述符

java - 从线程外部、线程运行内部设置 boolean 值

multithreading - iOS 上的 GCD 可以处理数百个已调度的 block 吗?

mysql - MySQL插入意向锁的解决方法

go - 我怎样才能生成依赖于它们的前辈的例程?

java - SOLR 4.x 与 3.x 解析查询的差异

java - 为 Windows Mobile 6.1 选项编写应用程序?

java - 从 dl.util.concurrent 迁移到 java.util.concurrent 的概述/教程