我想在互斥锁上锁定一个Map<String, Mutex> m
,同时还要确保获取该锁的行为是线程安全的:
//Assuming till here m.get(key) return a non-null value
synchronized (Mutex mtx = m.get(key)) {
mtx.count++;
//...
}
Java不保证以下内容
Mutex mtx = m.get(key);
synchroinzed (mtx) {
//thread 2 may acquire lock before thread 1 even thread 1 execute first
}
而且也不是
synchronized (m.get(key)) {
Mutex mtx = m.get(key);
//mtx could be null if other threads remove the key between 2 statements
//because lock is only acquired on m.get(key), not m itself
}
我怎样才能安全地做到这一点?
编辑:
我现在的确切代码:
public static <T, V> void lock (Map<T, Mutex<V>> mm, T uniqueKeyValue1, long waitMs) throws Mutex.WaitTimeoutException, InterruptedException {
synchronized ( MapUtils.putIfAbsentRetNewVal(mm, uniqueKeyValue1, new Mutex<V>()) ) {
Mutex<V> m = mm.get(uniqueKeyValue1);
if (m.getLockCount() == 0) {
m.incrementLockCount();
}
else {
m.incrementLockCount();
m.wait(waitMs);
if (m.getValue() == null) {
throw new Mutex.WaitTimeoutException();
}
}
}
}
最佳答案
这不是问题,与资源无关。使用选项2。您要的内容无法解决该问题。您需要的不是with资源,而是可以在地图上同步,然后在互斥锁上同步,然后在地图上释放同步的东西。由于静态作用域,您无法通过同步来做到这一点。
实际上,您需要的是另一个Mutex。或者,只接受比赛。这是良性的。您不在乎哪个线程首先执行。
关于java - 在获取锁定对象时还必须同步“与资源同步”吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32980412/