gpt4 book ai didi

java - 锁定或等待缓存加载

转载 作者:行者123 更新时间:2023-11-30 08:21:24 28 4
gpt4 key购买 nike

我们需要锁定负责将数据库日期加载到基于 HashMap 的缓存中的方法。

一种可能的情况是,当第一个方法仍在加载缓存时,第二个线程试图访问该方法。

我们认为第二个线程在这种情况下的努力是多余的。因此,我们希望第二个线程等待第一个线程完成,然后返回(无需再次加载缓存)。

我有什么用,但看起来很不雅观。有更好的解决方案吗?

private static final ReentrantLock cacheLock = new ReentrantLock();
private void loadCachemap() {
if (cacheLock.tryLock()) {
try {
this.cachemap = retrieveParamCacheMap();
} finally {
cacheLock.unlock();
}
} else {
try {
cacheLock.lock(); // wait until thread doing the load is finished
} finally {
try {
cacheLock.unlock();
} catch (IllegalMonitorStateException e) {
logger.error("loadCachemap() finally {}",e);
}
}
}
}

最佳答案

我更喜欢使用读锁和写锁的更具弹性的方法。像这样的东西:

private static final ReadWriteLock cacheLock = new ReentrantReadWriteLock();
private static final Lock cacheReadLock = cacheLock.readLock();
private static final Lock cacheWriteLock = cacheLock.writeLock();

private void loadCache() throws Exception {
// Expiry.
while (storeCache.expired(CachePill)) {
/**
* Allow only one in - all others will wait for 5 seconds before checking again.
*
* Eventually the one that got in will finish loading, refresh the Cache pill and let all the waiting ones out.
*
* Also waits until all read locks have been released - not sure if that might cause problems under busy conditions.
*/
if (cacheWriteLock.tryLock(5, TimeUnit.SECONDS)) {
try {
// Got a lock! Start the rebuild if still out of date.
if (storeCache.expired(CachePill)) {
rebuildCache();
}
} finally {
cacheWriteLock.unlock();
}
}
}
}

请注意,storeCache.expired(CachePill) 检测到一个陈旧的缓存,它可能比您想要的更多,但这里的概念是相同的,在更新缓存之前建立写锁,这将拒绝所有读取尝试,直到重建完成。此外,在某种循环中管理多次写入尝试,或者只是退出并让读锁等待访问。

从缓存中读取现在看起来像这样:

public Object load(String id) throws Exception {
Store store = null;
// Make sure cache is fresh.
loadCache();
try {
// Establish a read lock so we do not attempt a read while teh cache is being updated.
cacheReadLock.lock();
store = storeCache.get(storeId);
} finally {
// Make sure the lock is cleared.
cacheReadLock.unlock();
}
return store;
}

这种形式的主要好处是读取访问不会阻止其他读取访问,但在重建期间一切都会干净地停止 - 甚至其他重建。

关于java - 锁定或等待缓存加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25245371/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com