此设置是否可用作服务器端缓存?值是否会留在内存中而不是GC?
Servlet在app server启动时创建,是应用程序中唯一的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) { .. }
}
答案 0 :(得分:1)
这看起来并没有任何明显的缺陷。 除了缓存可以填满和崩溃的事实,因为没有任何东西可以自动删除旧条目。
如果你在使用缓存时不小心,你可能会引入一个可能会一直填满的微妙的内存泄漏。
答案 1 :(得分:0)
这将有效,但它也会无限制地增长,并且它是侵入性的(所有代码都必须知道缓存;它不实现Map
)。使用Guava缓存可能是一个更实用的选择。
答案 2 :(得分:0)
可能这不是你问的问题的答案,但为什么你不想使用像EhCache这样的东西?它已经实现了缓存解决方案并且运行良好:)
EDIT 但回答你的问题 - 我认为你的解决方案也应该有效:)
答案 3 :(得分:0)
您的Servlet
init
方法只会被调用一次/ JVM,因此您的synchronized
Cache
方法不需要init
。
您主要需要synchronize
方法填充您的cache
,在您的情况下,即使我认为不需要,因为您正在使用concurrenthashmap
答案 4 :(得分:0)
最简单的方法是使用WeakHashMap。您还可以查看基于SoftReferences的Guava CacheBuilder。 GC对这两种类型的引用进行了不同的收集。 SoftReferences更适合缓存,但JSE中没有内置实现。
答案 5 :(得分:0)
您可以使用类似的东西,只需确保将所有值包装在WeakReference
中。你仍然可以获得密钥的增长。当您发现弱引用无效时,您可以扫描并清除密钥,清除get
中的密钥,如果您不需要WeakHashMap
功能,则可以使用ConcurrentHashMap
。
答案 6 :(得分:0)
最好使用ServletContext上的属性,至少Tomcat的ApplicationContext使用CHM。