假设我有多个字符串值(动态生成)和一个线程池,并且我希望每个字符串值在任何时候都最多由一个线程独占。因此,例如,如果字符串“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
包中的哪些并发原语最适合此任务?
你需要这样的东西
如果您搜索网络,您可能会找到现有的实现。
假设
ConcurrentHashMap.compute()
是原子的,那么可以稍微重写接受的答案如下: