以下类充当一个简单的缓存,它很快就会更新(例如每天两次),并且可以读取很多(每秒最多几次)。有两种不同的类型,List
和Map
。我的问题是关于在update
方法中更新数据后的新分配。新数据应用的最佳(最安全)方式是什么?
我应该补充一点,读者没有必要看到绝对的最新价值。要求只是在任何给定时间获得旧值或新值。
public class Foo {
private ThreadPoolExecutor _executor;
private List<Object> _listObjects = new ArrayList<Object>(0);
private Map<Integer, Object> _mapObjects = new HashMap<Integer, Object>();
private Object _mutex = new Object();
private boolean _updateInProgress;
public void update() {
synchronized (_mutex) {
if (_updateInProgress) {
return;
} else {
_updateInProgress = true;
}
}
_executor.execute(new Runnable() {
@Override
public void run() {
try {
List<Object> newObjects = loadListObjectsFromDatabase();
Map<Integer, Object> newMapObjects = loadMapObjectsFromDatabase();
/*
* this is the interesting part
*/
_listObjects = newObjects;
_mapObjects = newMapObjects;
} catch (final Exception ex) {
// error handling
} finally {
synchronized (_mutex) {
_updateInProgress = false;
}
}
}
});
}
public Object getObjectById(Integer id) {
return _mapObjects.get(id);
}
public List<Object> getListObjects() {
return new ArrayList<Object>(_listObjects);
}
}
如您所见,目前不使用ConcurrentHashMap
或CopyOnWriteArrayList
。唯一的同步是在update方法中完成的。
虽然对于我目前的问题不是必需的,但是对于读者总是获得绝对最新价值的情况知道最佳解决方案也是很好的。
答案 0 :(得分:1)
除非您每秒阅读超过10,000次,否则您可以使用计划同步。
如果你想要并发访问,我会使用并发集合,如ConcurrentHashMap或CopyOnWriteArrayList。这些比同步集合更简单。 (即出于性能原因你不需要它们,为简单起见使用它们)
BTW:一个现代化的CPU可以在0.1秒内执行数十亿次操作,因此计算机每秒可以进行数次操作。答案 1 :(得分:0)
我也看到了这个问题并想到了多种解决方案: