[英]Quick and Easy Server Side Cache?
此设置是否可以用作服务器端缓存? 这些值会保留在内存中并且不会得到GC吗?
Servlet是在应用服务器启动时创建的,并且是应用程序中唯一的Servlet。 因此,如果Servlet停止,则应用程序将关闭。 该应用程序只能在一个JVM上运行。
public class HtmlServlet extends HttpServlet
{
private ConcurrentHashMap<String, Object> cache;
public void init() throws ServletException
{
cache = Cache.init();
}
}
public class Cache
{
private static ConcurrentHashMap<String, Object> cache;
public synchronized static ConcurrentHashMap<String, Object> init()
{
if (cache == null)
{
cache = new ConcurrentHashMap<String, Object>();
}
return cache;
}
public static void set(String s, Object o) { ... }
public static Object get(String s) { ... }
public static void remove(String s) { .. }
}
看起来没有任何明显的缺陷。 也许除了高速缓存可能会填满并崩溃的事实外,因为没有什么东西会自动删除旧条目。
如果您在使用缓存时不小心,可能会导致微妙的内存泄漏,它可能会不断填满。
这将起作用,但是它也会无限增长,并且具有侵入性(您的所有代码都必须了解缓存;它没有实现Map
)。 使用番石榴缓存可能是更实际的选择。
可能不是您所提问题的答案,但是为什么您不想使用诸如EhCache之类的东西呢? 它已经实现了缓存解决方案,效果很好:)
编辑但回答您的问题-我认为您的解决方案也应该起作用:)
您的Servlet
init
方法/ JVM仅被调用一次,因此不需要在Cache
init
方法中进行synchronized
。 您主要需要synchronize
将填充cache
,在您的情况下,我认为这甚至是不需要的,因为您正在使用concurrenthashmap
最简单的方法是使用WeakHashMap 。 您还可以查看基于SoftReferences的Guava CacheBuilder 。 GC收集这两种类型的引用的方式有所不同。 SoftReferences更适合于缓存,但是JSE中没有内置的实现。
您可以使用类似的方法,只需确保将所有值包装在WeakReference
。 您仍将获得更多的钥匙。 您可以扫描并清除键,在注意到弱引用无效时清除get
键,或者如果不需要ConcurrentHashMap
功能,则使用WeakHashMap
。
您最好在ServletContext上使用属性,至少Tomcat的ApplicationContext使用CHM。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.