可以从一个线程转移到另一个线程的锁定

时间:2011-01-27 06:35:37

标签: java concurrency locking atomic semaphore

我正在寻找一种类型的锁,其中持有锁的线程可以将其传递给它选择的另一个线程。

这就是我想要它的原因:

  • 我有一个类似于ConcurrentHashMap的类 - 一个专门的集合,分为多个部分
  • 大多数修改只需要锁定一个段。一些需要锁定两个段(具体来说,修改一个键,使其从一个段移动到另一个段。)
  • 大多数读取都不需要锁定 - 易失性读取通常就足够了,但如果修改计数检查失败,搜索需要立即锁定所有段
  • 搜索是在多个线程中完成的(通过ThreadPoolExecutor
  • 搜索功能必须具有所有段的一致视图(例如,当它从一个段移动到另一个段时,它不能错过一个条目。)
  • 搜索任务(针对单个细分)可能随时中断。

现在我正在考虑在主线程中调用搜索方法并发现它需要锁定所有段的情况。所有段锁必须由主线程一次保持(以确保没有干扰)但它不是将进行更新的主线程 - 它是工作线程之一。因此,一旦它知道它具有一致的快照,我试图让主线程“传递”锁。

我们过去常常为整个集合使用一个锁,但随着它变得越来越大,争用太多,小更新的延迟也无法接受。

解锁和重新锁定(在ReentrantLock上)是不安全的 - 另一个线程可能会在工作线程开始搜索之前修改该段。

普通Semaphore可以处理不同线程的锁定和解锁。然后出现的问题是谁应该释放信号量 - 工作线程需要一种方式来表明它已取得锁的所有权(因为它可能在此点之前或之后抛出异常并且主线程需要知道是否要清理单位测试也很棘手,因为你永远不知道信号量是否在正确的线程中获得或释放。

如果锁可以在其他方法中重复使用(它不会在线程之间传递),那将是一个额外的好处。)

我想要调用SemaphoreAtomicBooleanAtomicReference的某种组合,但快速谷歌搜索没有透露任何示例。有没有理由不采用这种方法?

1 个答案:

答案 0 :(得分:2)

反向使用读/写锁可能有效。在这个习语中,读锁定持有者执行对数据结构的并发写入(例如,阵列中的独立时隙)。写锁定用于获取独占访问以执行一致读取(例如,对数组求和)。这是一种很少使用的习语,但在那些古怪的情况下却很优雅。你的问题有点难以理解,但这至少可以为具体的解决方案提供一些灵感。我怀疑有了更深入的了解,问题可以简化,以便经典的解决方案更合适。