我有一个缓存列表,我的代码看起来像这样:
由于列表加载非常繁重,我收到了一个请求:如果列表加载当前正在进行中,则返回“旧”的缓存数据...这种情况是否可能发生?有没有人能给出我在这方面如何操作的指导?
编辑:Adam Horvath和bayou.io建议像下面这样处理。
我有一个缓存列表,我的代码看起来像这样
public class MyList {
private final List<String> cache = new ArrayList<String>();
private List<String> loadMyList() {
// HEAVY OPERATION TO LOAD DATA
}
public List<String> list() {
synchronized (cache) {
if( cache.size() == 0 ) {
cache.addAll(loadMyList());
}
return Collections.unmodifiableList(cache);
}
}
public void invalidateCache() {
synchronized (cache) {
cache.clear();
}
}
}
由于列表加载非常繁重,我收到了一个请求:如果列表加载当前正在进行中,则返回“旧”的缓存数据...这种情况是否可能发生?有没有人能给出我在这方面如何操作的指导?
编辑:Adam Horvath和bayou.io建议像下面这样处理。
public class MyList
{
private final List<String> cache = new ArrayList<String>();
private final List<String> oldCache = new ArrayList<String>();
private volatile boolean loadInProgress = false;
private List<String> loadMyList()
{
// HEAVY OPERATION TO LOAD DATA
}
public List<String> list()
{
synchronized (cache)
{
if( loadInProgress )
return Collections.unmodifiableList( oldCache );
else
return Collections.unmodifiableList(cache);
}
}
public void invalidateCache()
{
synchronized (cache)
{
// copy to old cache
oldCache = new ArrayList<String>( cache );
// set flag that load is in progress
loadInProgress = true;
// clear cache
cache.clear();
// initialize load in new thread
Thread t = new Thread(new Runnable()
{
public void run()
{
cache.addAll( loadMyList() );
// set flag that load is finished
loadInProgress = false;
}
});
t.start();
}
}
}
这个修改后的代码会有什么问题吗?由于我对多线程和/或缓存优化不熟悉,因此我希望得到所有性能建议。
list()
的人会得到你列表的视图 - 这意味着当你清空/重新填充列表时,仍然拥有该视图副本的调用者可能会看到列表处于不稳定状态。你确定你想要这样吗?此外,在你的例子中没有“旧”数据 - 列表要么为空,要么有一些内容,但一旦加载完成,就不会再更新了... - assylias