Я пытаюсь создать механизм блокировки на основе ключей: что-то вроде обычной блокировки реентера, но вместо блокировки() и unlock() вы блокируете (ключ) и разблокируете (ключ), с контрактом, что нет -one сможет блокировать (key1) одновременно, если key.equals(key1).
Будет ли этот код работать? Существуют ли более эффективные решения? Мне особенно не нравится цикл while, пытаясь поместить замок на карту...
package luca;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.ReentrantLock;
public class KeyedReentrantLock<K> {
private ConcurrentMap<K, ReentrantLock> lockMap = new ConcurrentHashMap<K, ReentrantLock>();
public void lock(K key) {
ReentrantLock oldLock = lockMap.get(key);
if (oldLock != null && oldLock.isHeldByCurrentThread()){
// increase lock count and return.
oldLock.lock();
return;
}
ReentrantLock newLock = new ReentrantLock();
newLock.lock();
while ((oldLock = lockMap.putIfAbsent(key, newLock)) != null){
// wait for the old lock to be released;
oldLock.lock();
oldLock.unlock();
}
return;
}
public void unlock(K key){
ReentrantLock lock = lockMap.get(key);
if (lock == null) throw new IllegalMonitorStateException("There was no lock for this key!");
if (lock.getHoldCount() == 1){
lockMap.remove(key);
}
lock.unlock();
}
}