我正在寻找一个简单的 Java 内存缓存,它具有良好的并发性(所以 LinkedHashMap 不够好) ,并且可以定期序列化到磁盘。
我需要的一个特性是一种“窥视”对象的方法,但这已被证明是很难找到的。这意味着从缓存中检索一个对象,而不会导致缓存持有该对象的时间比其他情况下更长。
更新: 我没有提到的另一个需求是,我需要能够就地修改缓存的对象(它们包含浮点数组)。
Can anyone provide any recommendations?
这个怎么样: https://commons.apache.org/proper/commons-jcs/(更新到新地址,因为 JCS 现在在 Apache Commons 中)
Ehcache 是一个非常好的解决方案,并且有一种方法可以查看(安静是这种方法) ,这样它就不会更新空闲时间戳。在内部,Ehcache 是通过一组映射实现的,类似于 ConcurrentHashMap,因此它具有类似的并发优势。
尝试 Ehcache? 它允许您插入您自己的缓存到期算法,以便您可以控制您的偷看功能。
您可以序列化到磁盘、数据库、跨集群等。
如果你需要简单的东西,这个合适吗?
Map<K, V> myCache = Collections.synchronizedMap(new WeakHashMap<K, V>());
It wont save to disk, but you said you wanted simple...
相关网址:
(正如 Adam 评论的那样,同步地图对性能有很大影响。并不是说这个想法毫无根据,但是作为一个快速而肮脏的解决方案就足够了。)
Try this:
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; } }
因为这个问题最初是问的,所以 Google's Guava library现在包含了一个强大而灵活的缓存。
您可以很容易地使用 Imcache。
void example(){ Cache<Integer,Integer> cache = CacheBuilder.heapCache(). cacheLoader(new CacheLoader<Integer, Integer>() { public Integer load(Integer key) { return null; } }).capacity(10000).build(); }
内存中 Java 缓存的另一个选项是 Cache2k。 内存性能优于 EHCache 和谷歌番石榴,见 cache2k benchmarks page。
使用模式与其他缓存类似,下面是一个例子:
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");
If you have google guava as dependency then trying out guava cache, may be a good alternative.
试试 Jcabi 方面中的 @Cacheable。只需要一个注释,就可以将整个方法的结果缓存到内存中:
@Cacheable
public class Resource { @Cacheable(lifetime = 5, unit = TimeUnit.SECONDS) public String load(URL url) { return url.openConnection().getContent(); } }
Also, read this article: http://www.yegor256.com/2014/08/03/cacheable-java-annotation.html