通常我会锁定如下所示的关键部分。
public class Cache {
private Object lockObject = new Object();
public Object getFromCache(String key) {
synchronized(lockObject) {
if (cache.containsKey(key)) {
// key found in cache - return cache value
}
else {
// retrieve cache value from source, cache it and return
}
}
}
}
我的想法是避免竞争条件,这可能导致数据源被多次命中并且密钥被多次添加到缓存中。
现在,如果两个线程大约同时进入不同的缓存键,我仍然会阻止一个。
假设钥匙是唯一的 - 通过锁定钥匙,锁还能工作吗?
我认为这是行不通的因为我知道对象引用应该相同才能使锁生效。我想这取决于它如何检查平等。
public class Cache {
public Object getFromCache(String key) {
synchronized(key) {
if (cache.containsKey(key)) {
// key found in cache - return cache value
}
else {
// retrieve cache value from source, cache it and return
}
}
}
}
public class Cache {
private static final Set<String> lockedKeys = new HashSet<>();
private void lock(String key) throws InterruptedException {
synchronized (lockedKeys) {
while (!lockedKeys.add(key)) {
lockedKeys.wait();
}
}
}
private void unlock(String key) {
synchronized (lockedKeys) {
lockedKeys.remove(key);
lockedKeys.notifyAll();
}
}
public Object getFromCache(String key) throws InterruptedException {
try {
lock(key);
if (cache.containsKey(key)) {
// key found in cache - return cache value
}
else {
// retrieve cache value from source, cache it and return
}
} finally {
unlock(key);
}
}
}
-
最后尝试- 非常重要 - 即使您的操作抛出异常,您也必须保证在操作后解锁等待线程。
- 如果您的后端分布在各个地方,它将无法工作多个服务器/JVM.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)