2014-06-08 79 views
0

我實現了一個Object緩存,像這樣:的Java:對垃圾收集賽車

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

圖片下面的比賽條件的場景:

  1. cache.containsKey(obj)回報true
  2. 垃圾收集器開始並收集緩存中的對象。
  3. null被返回。

的問題是:

  • 可這真的會發生? AFAIK GC可以在任何時間踢任何時間。
  • Java GC可以禁用單個方法調用嗎?​​似乎不能阻止GC。
  • 是否有任何解決方法?

在此先感謝!

+0

您正在濫用'WeakHashMap'。 – SLaks

+0

@SLaks請你詳細說明爲什麼? – MBlanc

+0

在這種情況下,您既有弱鍵也有弱值。 –

回答

1

這真的會發生嗎?

是。

Java GC可以禁用單個方法調用嗎?

是否有任何變通辦法?

是:試圖從緩存中檢索(從而建立如果它仍然在高速緩存中的強引用)的對象,並添加到緩存中如果引用是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)。

0

是否需要WeakHashMap和WeakReference?你可以使用普通的HashMap和普通的鍵,然後使用一個定時器線程來清除HashMap中的舊值。 GC是相當不可預知的,所以除非你不介意在你的地圖中有空值,我建議使用普通的值。

對於併發性,請看Java 7 Lock接口。就控制和性能而言,它比同步方法好得多。檢查此區塊是否有關於Java Lock Example and Concurrency Lock vs synchronized