具有多个对象/锁的Java同步
我想知道是否有一个包或模型可以帮助我解决这个问题。
假设我有3个线程和一堆对象A,B,C,D,E,F
- T1需要锁A,B
- T2需要锁B,C,D
- T3需要锁E,F
在这种情况下,如果T1和T3同时运行就没问题。 此外,T2和T3可以同时运行。 但T1和T2不应该同时运行。
另外,请注意
- 线程可以获得任意数量的锁,而不仅仅是2.(我看到了一个优雅的解决方案来解决这个问题,但是我不能确定我可以在这里应用它。)
- 显然,我希望每个线程同时获取所有需要的锁以防止死锁。
如果有人可以指向我支持此用例的程序包,或解决此问题的一些代码片段,请告诉我。
非常感谢。
步骤1
为您的资源提供自然的顺序。 例如,如果您的资源是字母, A
将出现在B
之前, B
将出现在C
之前,依此类推。
第2步
只允许您的线程按顺序获取资源。
现在你的线程在任何情况下都不可能达到死锁。
例
- 线程1需要锁定资源
A
,B
,D
和E
- 线程2需要锁定资源
B
和E
我们的线程必须争取资源B
和D
锁定。 因为我们已经强制执行自然顺序,所以首先获得B
上的锁定的线程可以保证在D
上获得锁定并顺利进行。 失败的线程将等待B
被释放。
为了避免在这些情况下发生死锁,您必须引发锁定的排序,并根据您的应用程序一致地根据引发的顺序获取它们。
我理解这个答案已被提及,特别是在你的情况下可能就足够了,但只有当对象具有可比性时才有可能进行自然排序:(
诱导对象排序的最佳方法是使用返回hashcode值的System.identityHashCode(A / B / C … lock对象)。 但是再次感觉不是100%安全,因为你可能是哈希冲突的受害者,甚至机会很少,但你可能会遇到死锁。 在这些情况下,您的代码需要额外的安全性。 你让你的线程竞争一些单独的’打破’锁定。 希望这些信息有助于更清楚地了解您的问题。