具有多个对象/锁的Java同步

时间:2014-02-12 20:38:59

标签: java multithreading concurrency synchronization locks

我想知道是否有一个包或模型可以帮我解决这个问题。

假设我有3个线程和一堆对象A,B,C,D,E,F

  • T1需要锁A,B
  • T2需要锁B,C,D
  • T3需要锁E,F

在这种情况下,如果T1& T3同时运行。此外,T2& T3可以同时运行。但是T1& T2不应该同时运行。

另外,请注意

  • 线程可以获得任意数量的锁,而不仅仅是2.(我看到这个问题的优雅解决方案有固定数量的锁,但不确定我可以在这里应用它。)
  • 显然,我希望每个线程同时获取所有需要的锁以防止死锁。

如果有人可以指向我支持此用例的程序包,或者解决此问题的一些代码段,请告知我们。

非常感谢。

2 个答案:

答案 0 :(得分:4)

第1步

为您的资源提供自然顺序。例如,如果您的资源是字母,A将在B之前出现,B将出现在C之前,依此类推。

第2步

只允许您的线程按顺序获取资源。

现在你的线程在任何情况下都不可能达到死锁。

示例

  • 线程1需要锁定资源ABDE
  • 线程2需要锁定资源BE

我们的主题必须争取锁定资源BD。因为我们已经强制执行自然顺序,所以首先获得B锁定的线程可以保证锁定D并顺利进行。失败的线程将等待B被释放。

答案 1 :(得分:2)

为避免在这些情况下发生死锁,您必须在锁定时引入一个排序,并根据您的应用程序一致地根据引导顺序获取它们。

我理解这个答案已被提及,特别是在你的情况下可能就足够了,但只有当对象具有可比性时才有可能进行自然排序:(

诱导对象排序的最佳方法是使用返回hashcode值的System.identityHashCode(A / B / C ... lock对象)。但是再次感觉不是100%安全,因为你可能是哈希冲突的受害者,即使机会很少,但你可能会遇到死锁。在这些情况下,您需要在代码中增加安全性。你让你的线程竞争一些单独的'打破'锁定。希望这些信息有助于更清楚地了解您的问题。