考虑我有许多字符串值(动态生成)和一个线程池,并且我希望每个字符串值在任何时候都最多由一个线程独占。因此,例如,如果字符串“foo”在某个时间段被线程T1锁定,则所有其他线程等待处理“foo”(或任何其他字符串等于到“foo”) Object.equals()
)必须等待,直到线程T1 释放锁。 所以我想实现以下接口:
interface Lock {
void lock(@NonNull String key);
void unlock(@NonNull String key);
}
正如我所说,如果密钥已被其他线程锁定,则任何进入 lock(String)
方法的线程都应该等待(或中断地等待,或超时等待)。并且
unlock(String)
方法应该有效地解锁密钥,在两种情况下抛出异常:
ReentrantLock
实例与任何即将锁定的键关联起来,使其始终保持锁定状态。如何实现
LockByKey
接口?
java.util.concurrent
包中的哪些并发原语最适合此任务?
public class StringLockImpl implements StringLock {
private final Map<String, LockObject> map = new HashMap<>();
private final Lock lock = new ReentrantLock();
@Override
public void lock(String key) {
acquire(key).lock();
}
@Override
public void unlock(String key) {
release(key).unlock();
}
private Lock acquire(String key) {
lock.lock();
try {
LockObject lockObject = map.computeIfAbsent(key, ignore -> new LockObject());
lockObject.inc();
return lockObject.getLock();
} finally {
lock.unlock();
}
}
private Lock release(String key) {
lock.lock();
try {
LockObject lockObject = map.computeIfAbsent(key, ignore -> new LockObject());
if (lockObject.dec()) {
map.remove(key);
}
return lockObject.getLock();
} finally {
lock.unlock();
}
}
private static class LockObject {
private int counter;
@Getter
private final Lock lock = new ReentrantLock();
public void inc() {
counter++;
}
public boolean dec() {
return --counter == 0;
}
}
}
如果您搜索网络,您可能会找到现有的实现。