【发布时间】:2014-08-11 14:12:00
【问题描述】:
我们需要锁定一个负责将数据库日期加载到基于 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);
}
}
}
}
【问题讨论】:
-
您的流程将只确保
retrieveParamCacheMap()在此流程中不会被调用,即从loadCachemap()。任何其他线程都可以从不同的地方调用您的retrieveParamCacheMap()。这是你想要的吗? -
retrieveParamCacheMap() 设置为私有,对它的任何访问都会经过这个加载方法。但是,你的观点很清楚。为了更安全,可能需要进一步分开。
-
只有当第二个(以及任何后续)线程执行此代码,而第一个线程正在处理它并持有锁时,您的解决方案才有效。但是一旦它完成并释放锁,下一个线程将在
tryLock()上成功,因此开始创建新地图。
标签: java multithreading concurrency locking