2010-02-12 19 views
9

我以前得出的結論是,如果您需要一個基於值(等於)的相等的SoftReference,那麼一個人的設計不好,除了這個人以外。這是繼谷歌收藏和番石榴不包括這樣一個類。但是我遇到了一個我認爲可以使用這樣一個對象的問題。SoftReference具有值(等於)等於的潛在用途

我們在一個視覺效果渲染農場中有一個資產管理系統,它有100個運行相同作業的進程,這些進程只在渲染的幀號上有所不同。我們有一個Oracle數據庫,需要記錄所有使用的資產。在中間層資產管理系統中,我們可以使用HashSet來記錄是否將插入到Oracle中的對象,而不是用相同的插入方式敲擊Oracle,而只有一個插入方式可以從所有作業中成功完成。

我可以使用Google MapMaker過期,但我不想擔心獲得正確的到期日期,我們已經呈現在幾小時內和幾天內運行。使用SoftReference以及equals equals聽起來像是一種更好的方式,所以JVM會自動管理垃圾收集。

對於我想用帶垃圾回收功能的ConcurrentHashMap解決的其他問題,我將在HashMap中使用強引用作爲獲取equals()相等和SoftReference作爲值的關鍵,以便JVM可以垃圾回收,但在這種情況下,值並不重要,我沒有一個值包含在SoftReference中放在那裏。所以看起來像使用equals()的SoftReference可以做到這一點。

對此有何建議?

+1

愛你的問題,我最近也一直在想這個 – nanda 2010-02-12 07:58:56

+0

不是'ResourceBundle'做這樣的事情嗎? – 2010-02-12 08:22:27

+0

@nanda Oracle中添加的內容是動態生成的資產列表(稱爲NFS服務器上的文件名); ResourceBundle似乎並不適合。我只需要一個HashSet來記錄文件名被記錄在Oracle中,所以另外99次嘗試插入它不會浪費Oracle中的CPU週期。 – 2010-02-12 15:53:50

回答

1

在大多數情況下,當你想使用谷歌集合軟引用,你應該叫

MapMaker.softValues() 

憑藉強大的密鑰,但軟值,查找將用平等和鍵值對將被垃圾收集時,內存很緊。

+0

但我沒有與鑰匙聯繫的價值,所以鑰匙是唯一可以放在軟參考中的東西。 – 2010-02-15 12:18:28

0

我認爲這個類將滿足你的需要:

import java.util.*; 
import java.lang.ref.*; 

public class SoftSet<T> extends AbstractSet<T> { 

    private final WeakHashMap<T,SoftReference<T>> data = new WeakHashMap<T,SoftReference<T>>(); 

    public boolean add(T t) { 
    return null == data.put(t, new SoftReference<T>(t)); 
    } 

    public boolean remove(Object o) { 
    return null != data.remove(o); 
    } 

    public boolean contains(Object o) { 
    return data.containsKey(o); 
    } 

    public Iterator<T> iterator() { 
    return data.keySet().iterator(); 
    } 

    public int size() { 
    return data.size(); 
    } 

    public void clear() { 
    data.clear(); 
    } 

    public boolean removeAll(Collection<?> c) { 
    return data.keySet().removeAll(c); 
    } 

    public boolean retainAll(Collection<?> c) { 
    return data.keySet().retainAll(c); 
    } 
} 

,這應該工作的方式是,一旦軟引用是價值被清除,則該值爲弱可只和關鍵可以從內部地圖中刪除。

+0

也許是downvote,因爲它將對象封裝在兩個單獨的引用中,而不是它需要的。在Google ConcurrentHashMap中有一個SoftReference子類與equals()相等,可能會更清晰。 – 2010-02-19 22:42:03

1

由於沒有ConcurrentHashSet使用軟引用,只有兩個辦法:

1)您與ConcurrentHashMap

  • 覆蓋equalshashCodeSoftReference
  • 裏面的equals方法和hashCode只能訪問使用的對象SoftReference#get
  • SoftReference作爲鍵,任何對象作爲值(僅空值不允許)
  • 如果引用在訪問hashCode或equals時過時,請將引用添加到刪除隊列中以頻繁刪除已死亡的鍵。
  • 檢查通過containsKey

2包含的內容。)使用ConcurrentMultimap<Integer, Set<SoftReference<RepLookupEntry>>並使用hashCode作爲鍵,並使用同步的SoftReferences作爲值。當您獲得hashCode命中時,請檢查所有SoftReferences的內容是否相等。不是很漂亮,我同意並且很難同步。

如果我處於你的位置,我根本不會使用SoftReferences,而是使用ConcurrentHashMap來保持對你的POJO的強引用。每次到達一個新元素時,都會將其放入一個ConcurrentLinkQueue中。如果隊列增長超過一定的限制,則從HashMap中刪除元素。