我有一个关键的过程,我必须确保在任何时候都不能处理两个等价的MyObject (可以是不同的实例,但在逻辑上是相等的)。下面的代码演示了这个想法:
public class MyClass {
public static ConcurrentMap<MyObject, String> concurrentMap = new ConcurrentHashMap<>();
public void process(MyObject myObject) {
String id = UUID.randomUUID().toString();
String existingId = concurrentMap.putIfAbsent(myObject, id);
synchronized (id) {
if (existingId == null) { // no others, start working right away
// do work
} else { // an equivalent myObject is under processing, wait on it
synchronized (existingId) {
// finally can start doing work
}
}
}
}
}上面的代码在synchronized的帮助下对一个随机字符串进行工作。但是这个代码的问题是
谢谢
发布于 2017-09-18 02:38:50
我不认为我真的理解这个想法的用例,这是一个巨大的危险信号。但在我看来,所有这些代码都是不必要的。如果这里唯一的想法是为myObject获得一个唯一的锁,那么您已经有了这样的想法:它是myObject。
public class MyClass {
public void process(MyObject myObject) {
synchronized (myObject) {
// finally can start doing work
}
}
}其余的代码都是死记硬背的。
然而,这仍然令人忧虑。由于您依赖于外部过程来同步您的对象,任何其他引用myObject的代码都可以做他们喜欢的任何事情,并且您无法控制它。这是一种非常弱的同步形式。如果代码库中的每个人都理解在他们的MyObject上同步的必要性,这是可以工作的,但这在实践中可能很难实现。
发布于 2017-09-18 06:03:21
我认为这库是你要找的东西。特别是StripedKeyLockManager和CountingLock类,它们解决了您的问题。您可以在项目中使用库,也可以根据需要调整其源代码。番石榴还通过剥光类提供了类似的功能。
https://stackoverflow.com/questions/46270744
复制相似问题