java - java - Spring框架中Collection的可能竞态条件
问题描述
我正在使用tomcat下的spring框架编写可以处理多个并发请求的服务。在我的服务类中声明了一个静态变量,将在所有线程之间共享并受读写锁保护。这个静态集合被定期读取和写入。每次更新时,我都会获得写锁,当我读取它时,我会获得读锁。
存储在集合中的数据是来自数据库表的条目。所以它是一个List类型的集合。基本上我有一个很少更新的表,所以我将它缓存在进程内存中。
现在有时我需要记录这些数据,所以我可以在不获取方法中的锁的情况下记录返回对象。或者这会导致比赛条件吗?日志记录是为了调试。
另外,集合的返回值是只读的,不能被任何方法修改。服务对象之外的任何人都不会使用此集合。
我觉得这应该可行,因为当分配新集合时,旧集合只有在所有对它的引用都消失时才会消失。并且在更新写锁之前,不允许对旧对象或新对象的新引用。
代码如下所示:
class ObjService {
private static Collection<OtherObj> _staticCollection;
private static ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock(true);
private Collection<OtherObj> getCollection () {
Collection<OtherObj> retVal = null;
rwlock.readLock().lock();
if (_staticCollection != null) {
retVal = _staticCollection;
rwlock.readLock().unlock();
log (retVal);
}
else {
rwlock.readLock().unlock();
ReloadCollectionFromDB ();
rwlock.readLock().lock();
retVal = _staticCollection;
rwlock.readLock().unlock();
}
}
private ReloadCollectionFromDB () {
Collection<OtherObj> otherObjCol = null;
try {
otherObjCol = objRepo.findAll ();
}
catch (Exception ex) {
// log exception
return;
}
rwlock.writeLock().lock();
_staticCollection = otherObjCol;
rwlock.writeLock().unlock();
}
// periodically get data from DB
@Scheduled(initialDelayString = "120000", fixedDelayString = "540000")
void readLoadCache () {
ReloadCollectionFromDB ();
}
}
如果有更好的方法可以做到这一点,我将不胜感激。
非常感谢,~Ash
解决方案
推荐阅读
- android - 如何添加不兼容的单独 Android 活动
- flutter - 我怎样才能让我的抽屉的孩子成为一个列?
- ios - UITableView.reloadData() 没有刷新 tableView。没有错误信息
- ios - 如何正确检查应用程序连接?
- android - 初始化 ADB 时出错:找不到 Android 调试桥
- kotlin - Kotlin native - 执行可执行文件
- python - 通过子进程调用时程序抛出错误
- ios - Parse 在第一次查询尝试时不返回
- android - 如何维护 Spinner 选择的状态?
- c++ - 如何在使用 2d 数组作为参数的同时创建 3d 数组