我已经实现了 Object
像这样缓存:
// Dictionary with weak keys & values
private Map<Object, WeakReference<Object>> cache = new WeakHashMap<>();
private Object checkCache(Object obj) {
// If it's in the cache, returned the cached copy.
if (cache.containsKey(obj)) return cache.get(obj).get();
// Store it in, and return it.
cache.put(obj, new WeakReference<>(obj));
return obj;
}
想象以下竞争条件场景:
-
cache.containsKey(obj)
返回true
- 垃圾收集器启动并获取缓存中的对象。
-
null
已返回。
问题是:
- 这真的会发生吗? AFAIK GC 可以在任何时间启动。
- 是否可以针对单个方法调用禁用 Java GC?
synchronized
似乎并不能阻止 GC。 - 有任何解决方法吗?
提前致谢!
最佳答案
Can this really happen?
是的。
Can Java GC be disabled for a single method call?
没有。
Are there any work-arounds?
是:您尝试从缓存中检索对象(如果该对象仍在缓存中,则建立强引用),如果该引用为 null
,则将其添加到缓存中:
WeakReference<Object> ref = cache.get(obj);
Object cached = (ref != null) ? ref.get() : null;
if (cached != null) {
return cached;
}
else {
cache.put(obj, new WeakReference(obj));
return obj;
}
您仍然需要同步该方法,否则可能有两个线程同时更新缓存(结果 update race 将是 least of your worries )。
关于Java:与垃圾收集器赛跑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24109126/