Pao*_*976 15 java concurrency concurrenthashmap
我想在Web java应用程序中实现对重量级对象的简单缓存.但我无法弄清楚如何正确地做到这一点.
我错过了什么或ConcurrentHashMap方法(putIfAbsent,...)是不够的,需要额外的同步?
是否有更好的简单API(在内存中,没有外部配置)来做到这一点?
P.
Cow*_*wan 25
继肯的回答,如果在创建后来被扔掉一个重量级的对象是不接受(要保证只有一个对象被每个键创建的,由于某种原因),那么你可以做到这一点....其实,别.不要自己动手.使用google-collections(现为番石榴)MapMaker类:
Map<KeyType, HeavyData> cache = new MapMaker<KeyType, HeavyData>()
.makeComputingMap(new Function<KeyType, HeavyData>() {
public HeavyData apply(KeyType key) {
return new HeavyData(key); // Guaranteed to be called ONCE for each key
}
});
Run Code Online (Sandbox Code Playgroud)
然后,一个简单的cache.get(key)只是工作,并从不必担心并发性和syncrhonization的棘手方面完全删除你.
请注意,如果您想添加一些更有用的功能,例如到期,那就是
Map<....> cache = new MapMaker<....>()
.expiration(30, TimeUnit.MINUTES)
.makeComputingMap(.....)
Run Code Online (Sandbox Code Playgroud)
如果需要,您还可以轻松地为键或数据使用软值或弱值(有关详细信息,请参阅Javadoc)
小智 14
如果对于您尝试缓存的事物临时拥有多个实例是安全的,则可以执行如下所示的"无锁"缓存:
public Heavy instance(Object key) {
Heavy info = infoMap.get(key);
if ( info == null ) {
// It's OK to construct a Heavy that ends up not being used
info = new Heavy(key);
Heavy putByOtherThreadJustNow = infoMap.putIfAbsent(key, info);
if ( putByOtherThreadJustNow != null ) {
// Some other thread "won"
info = putByOtherThreadJustNow;
}
else {
// This thread was the winner
}
}
return info;
}
Run Code Online (Sandbox Code Playgroud)
多个线程可以"竞争"为密钥创建和添加项目,但只有一个应该"赢".
| 归档时间: |
|
| 查看次数: |
16462 次 |
| 最近记录: |