java - 通过 ReentrantReadWriteLock 中断等待的读取线程

标签 java concurrency resources

我有一个资源列表。读取进程可以同时访问其中的每一个,但有时写入进程会出现并更改对象,这要求在更新时没有读取进程在资源上运行。 Java 的 ReentrantReadWriteLock似乎可以正确处理这种情况,因此我已将其中一个分配给每个资源以最大化应用程序的吞吐量。但是我面临删除条目的问题。某些写入进程可能会从此列表中删除可访问的资源。

想象一下以下场景:

  • 删除进程获取被删除资源的锁
  • 与此同时,读取进程到达 readLock().lock() 语句并开始在队列中等待释放写锁
  • 删除进程从列表中删除资源并调用关闭资源以完成
  • 删除进程释放资源上的写锁
  • 恢复第一个等待的读取进程并开始处理现在不一致的资源对象

如何正确处理这种情况?如果我可以在等待读取线程上调用 interrupt() 就好了,但是作为 getQueuedReaderThreads 的 API 描述声明它不可靠,因为新线程可以在构建列表时获取读锁,所以我不能确定我会取消所有线程。

最佳答案

我认为将“已删除”标志与每个资源相关联会容易得多。

当读取器获得锁时,它应该检查该标志并正确处理资源被删除的情况。由于writer在删除资源后立即释放锁,而每个reader在发现资源被删除后应该立即释放锁,所以这里应该没有long blocking,所以不需要中断线程。

您可以将此行为隐藏在您自己的 API 后面(例如,当读取器获取对已删除资源的锁定时,您可以抛出类似 ResourceDeletedException 的内容)。

关于java - 通过 ReentrantReadWriteLock 中断等待的读取线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12836022/

相关文章:

java - 使用从外部类到主类的字符串

java - 多模式使用的副作用

JavaFX 图像错误

java - 为什么 getResource 为 NULL?

android - 如何访问android库自己的资源

java - java从mysql数据库读取docx文件

java - Tomcat7 在提取 war 文件时重写了我的 context.xml

Bash:如何简单地并行化任务?

Java 支持从大于 `Int.MAX_VALUE` 的 URL 下载数据 (Url.openConnection())

c# - ASP.NET Web API C# 并发请求导致数据库重复