我正在寻找一个具有良好并发性的简单Java内存缓存(因此LinkedHashMap不够好),并且可以定期将其序列化到磁盘。
我需要但很难找到的一个功能是一种“窥视”对象的方法。我的意思是从缓存中检索对象,而不会导致缓存对对象的保留时间超过其应有的保留时间。
更新:我忽略提到的另一个要求是,我需要能够就地修改缓存的对象(它们包含浮点数组)。
谁能提供任何建议?
我正在寻找一个具有良好并发性的简单Java内存缓存(因此LinkedHashMap不够好),并且可以定期将其序列化到磁盘。
我需要但很难找到的一个功能是一种“窥视”对象的方法。我的意思是从缓存中检索对象,而不会导致缓存对对象的保留时间超过其应有的保留时间。
更新:我忽略提到的另一个要求是,我需要能够就地修改缓存的对象(它们包含浮点数组)。
谁能提供任何建议?
Answers:
自从最初提出这个问题以来,Google的Guava库现在包括一个强大而灵活的缓存。我建议使用此。
Ehcache是一个很好的解决方案,它有一个偷看的方法(getQuiet()是方法),这样它就不会更新空闲时间戳。在内部,Ehcache是通过一组映射实现的,类似于ConcurrentHashMap,因此它具有类似的并发优势。
如果您需要简单的东西,这是否合算?
Map<K, V> myCache = Collections.synchronizedMap(new WeakHashMap<K, V>());
它不会保存到磁盘,但是您说过想要简单...
链接:
(正如亚当(Adam)所说,同步地图会降低性能。不是说这个想法没有毛病,但足以作为一种快速而肮脏的解决方案。)
ConcurrentHashMap<WeakReference<T>>
。docs.oracle.com/javase/7/docs/api/java/lang/ref/…–
内存中Java缓存的另一个选项是cache2k。内存性能优于EHCache和google番石榴,请参阅cache2k基准测试页面。
使用模式类似于其他缓存。这是一个例子:
Cache<String,String> cache = new Cache2kBuilder<String, String>() {}
.expireAfterWrite(5, TimeUnit.MINUTES) // expire/refresh after 5 minutes
.resilienceDuration(30, TimeUnit.SECONDS) // cope with at most 30 seconds
// outage before propagating
// exceptions
.refreshAhead(true) // keep fresh when expiring
.loader(new CacheLoader<String, String>() {
@Override
public String load(final String key) throws Exception {
return ....;
}
})
.build();
String val = cache.peek("something");
cache.put("something", "hello");
val = cache.get("something");
如果您将谷歌番石榴作为依赖项,那么尝试番石榴缓存可能是一个不错的选择。
您可以轻松使用imcache。下面是示例代码。
void example(){
Cache<Integer,Integer> cache = CacheBuilder.heapCache().
cacheLoader(new CacheLoader<Integer, Integer>() {
public Integer load(Integer key) {
return null;
}
}).capacity(10000).build();
}
试试这个:
import java.util.*;
public class SimpleCacheManager {
private static SimpleCacheManager instance;
private static Object monitor = new Object();
private Map<String, Object> cache = Collections.synchronizedMap(new HashMap<String, Object>());
private SimpleCacheManager() {
}
public void put(String cacheKey, Object value) {
cache.put(cacheKey, value);
}
public Object get(String cacheKey) {
return cache.get(cacheKey);
}
public void clear(String cacheKey) {
cache.put(cacheKey, null);
}
public void clear() {
cache.clear();
}
public static SimpleCacheManager getInstance() {
if (instance == null) {
synchronized (monitor) {
if (instance == null) {
instance = new SimpleCacheManager();
}
}
}
return instance;
}
}
public static SimpleCacheManager getInstance() {
应当public synchronized static SimpleCacheManager getInstance() {
否则if (instance == null) {
不是线程安全的。在这种情况下,你可以删除监控对象的所有在一起,因为同步发生的所有的getInstance()调用,请参阅:javaworld.com/article/2073352/core-java/...
@Cacheable
从jcabi-aspects尝试。使用单个注释,您可以使整个方法的结果可缓存在内存中:
public class Resource {
@Cacheable(lifetime = 5, unit = TimeUnit.SECONDS)
public String load(URL url) {
return url.openConnection().getContent();
}
}
另外,请阅读这篇文章:http : //www.yegor256.com/2014/08/03/cacheable-java-annotation.html
怎么样:https : //commons.apache.org/proper/commons-jcs/(已更新为新地址,因为JCS现在位于Apache Commons中)