假设我有以下(伪)代码:
class Cache {
Entry addIfMissing(String data) {
// omitted for brevity
}
void evictOldEntries() {
// omitted for brevity
}
}
class Program {
private Cache cache = new Cache();
doWork() { // called from multiple threads
var entry = cache.addIfMissing("omitted for brevity");
// work with entry
}
static {
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
cache.evictOldEntries();
}, 10, 10, TimeUnit.MINUTES);
}
}
我想确保evictOldEntries
方法正在运行时,程序中的所有其他线程都必须等待它完成。
在这种情况下哪种同步机制合适?
答案 0 :(得分:3)
您需要的是这样的
class Cache {
ReentrantLock lock;
public Cache { lock = new ReentrantLock(); }
Entry addIfMissing(String data) {
if (lock.isLocked) lock.wait();
// Add data here
}
void evictOldEntries() {
if (lock.tryLock()) {
try {
// Evict old entries
}
finally {
lock.unlock();
lock.notify();
}
}
}
}
答案 1 :(得分:1)
在这里请稍加自由,因为您的代码示例和确切要求尚不清楚。但是,这样的工作可能吗? ConcurrentHashMap
使用细粒度锁定,因此可以在将条目插入高速缓存时最大程度地减少瓶颈。退出线程甚至可以与插入线程同时运行。
class Cache<String, CacheEntry> {
ConcurrentHashMap<String, CacheEntry> map = new ConcurrentHashMap<String, CacheEntry>();
Entry addIfMissing(String data) {
map.computeIfAbsent(...);
}
void evictOldEntries() {
Iterator<Map.Entry<String, CacheEntry>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
CacheEntry entry = iterator.next().getValue();
if (shouldEvict(entry)) {
iterator.remove();
}
}
}
}
答案 2 :(得分:1)
我认为ReentrantReadWriteLock正是我所需要的:
[[1, 2]]
------
[[1]]
这样,一旦获得class Program {
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
void doWork() { // called from multiple threads
rwl.readLock().lock();
try {
var entry = cache.addIfMissing("omitted for brevity");
// work with entry
} finally {
rwl.readLock().unlock();
}
}
static {
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
rwl.writeLock().lock();
try {
cache.evictOldEntries();
} finally {
rwl.writeLock().unlock();
}
}, 10, 10, TimeUnit.MINUTES);
}
}
的writeLock,就必须阻止,反之亦然。