寻找简单的Java内存缓存

寻找简单的Java内存缓存,java,caching,Java,Caching,我正在寻找一个简单的Java内存缓存,它具有良好的并发性(因此LinkedHashMap不够好),并且可以定期序列化到磁盘 我需要的一个功能是“窥视”一个物体,但事实证明很难找到。我的意思是从缓存中检索一个对象,而不会导致缓存保留对象的时间比其他方式更长 更新:我没有提到的另一个要求是,我需要能够在适当的位置修改缓存对象(它们包含浮点数组) 有人能提供一些建议吗?这个怎么样:(更新到新地址,因为JCS现在在Apache Commons中)是一个很好的解决方案,并且有一种方法可以查看(即方法),这

我正在寻找一个简单的Java内存缓存,它具有良好的并发性(因此LinkedHashMap不够好),并且可以定期序列化到磁盘

我需要的一个功能是“窥视”一个物体,但事实证明很难找到。我的意思是从缓存中检索一个对象,而不会导致缓存保留对象的时间比其他方式更长

更新:我没有提到的另一个要求是,我需要能够在适当的位置修改缓存对象(它们包含浮点数组)

有人能提供一些建议吗?

这个怎么样:(更新到新地址,因为JCS现在在Apache Commons中)

是一个很好的解决方案,并且有一种方法可以查看(即方法),这样它就不会更新空闲时间戳。在内部,Ehcache是通过一组映射实现的,有点像ConcurrentHashMap,因此它具有类似的并发优势。

试试看?它允许您插入自己的缓存过期算法,以便控制peek功能


您可以序列化到磁盘、数据库、跨集群等。

如果您需要一些简单的东西,这是否合适

Map<K, V> myCache = Collections.synchronizedMap(new WeakHashMap<K, V>());
Map myCache=Collections.synchronizedMap(新的WeakHashMap());
它不会保存到磁盘,但你说你想要简单的

链接:

(正如Adam所评论的,同步地图会影响性能。并不是说这个想法没有意义,但作为一个快速而肮脏的解决方案就足够了。)

试试以下方法:

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;
    }

}
import java.util.*;
公共类SimpleCacheManager{
私有静态SimpleCacheManager实例;
私有静态对象监视器=新对象();
私有映射缓存=Collections.synchronizedMap(新的HashMap());
私有SimpleCacheManager(){
}
公共void put(字符串cacheKey,对象值){
cache.put(cacheKey,value);
}
公共对象获取(字符串缓存键){
返回cache.get(cacheKey);
}
公共无效清除(字符串缓存键){
cache.put(cacheKey,null);
}
公共空间清除(){
cache.clear();
}
公共静态SimpleCacheManager getInstance(){
if(实例==null){
同步(监视器){
if(实例==null){
实例=新的SimpleCacheManager();
}
}
}
返回实例;
}
}

由于最初提出了这个问题,现在包含了一个功能强大且灵活的缓存。我建议您使用它。

您可以轻松使用。下面是一个示例代码

void example(){
    Cache<Integer,Integer> cache = CacheBuilder.heapCache().
    cacheLoader(new CacheLoader<Integer, Integer>() {
        public Integer load(Integer key) {
            return null;
        }
    }).capacity(10000).build(); 
}
void示例(){
Cache Cache=CacheBuilder.heapCache()。
cacheLoader(新的cacheLoader(){
公共整数加载(整数键){
返回null;
}
}).容量(10000)。构建();
}

内存中java缓存的另一个选项是。 内存性能优于EHCache和google guava,请参阅

使用模式与其他缓存类似。以下是一个例子:

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");
Cache Cache=new Cache2kBuilder(){}
.expireAfterWrite(5,TimeUnit.MINUTES)//5分钟后过期/刷新
.resilienceDuration(30,TimeUnit.SECONDS)//最多处理30秒
//传播前的中断
//例外情况
.refreshAhead(true)//过期时保持新鲜
.loader(新的缓存加载器(){
@凌驾
公共字符串加载(最终字符串键)引发异常{
返回。。。。;
}
})
.build();
String val=cache.peek(“某物”);
cache.put(“某物”、“你好”);
val=cache.get(“某物”);
如果你依赖谷歌番石榴,那么尝试番石榴缓存可能是一个不错的选择。

从。通过一个注释,可以将整个方法结果缓存在内存中:

public class Resource {
  @Cacheable(lifetime = 5, unit = TimeUnit.SECONDS)
  public String load(URL url) {
    return url.openConnection().getContent();
  }
}

另外,请阅读本文:

谢谢,还有一个问题:如果我从EHcache检索一个对象(比如,一个数组),并对其进行修改,该对象会在缓存中更新吗?EHCache是否维护对对象的引用?我相信是的,但要安全地执行此操作,当然必须适当地锁定对象。我喜欢EHCache,但它是一个10mb的jar。太大了。我正在寻找类似的东西,是“在过程中”和更轻的重量。我想用它在堆中的Eclipse插件中存储一些数据。Ehcache和JCS对我来说似乎太重了/distributed/J2EE。我将推荐Apache Ignite()的可能副本此问题已解决(事实发生6年后),今天人们仍在疑惑,请说明SO的版主系统是如何失败的。同步整个巨大的地图是一个沉重的惩罚。您可以轻松地将弱类型存储在并发哈希映射中,并定期删除它们。ConcurrentHashMap比Collections好。synchronizedMap在性能方面,ConcurrentHashMap绝对性能更好,但在允许垃圾收集器回收内存方面,它与WeakHashMap没有相同的属性。这可能对您很重要,也可能不重要。然后使用
ConcurrentHashMap
。依赖同步映射的问题已经在其他答案中讨论过了。@sergeyB:我正在寻找一种类似的解决方案,该解决方案对于实现缓存非常简单。。。感谢
public static SimpleCacheManager getInstance(){
应该是
public synchronized static SimpleCacheManager getInstance(){
否则
如果(instance==null){
不是线程安全的。在这种情况下,您可以一起删除监视器对象,因为所有getInstance()都进行了同步调用,请参阅:我可以建议对singleton使用枚举吗?看起来@sanity需要一个轻缓存。cruftex,如果我关闭我的应用程序,缓存将销毁所有已注册的数据或否?请注意Spring不再支持Guava缓存:@sanity