Ich komme vorhin zu der Schlussfolgerung, dass, wenn Sie eine SoftReference mit Gleichwertigkeit auf der Grundlage von Wert (Gleichheit) benötigen, ein Entwurf schlecht war, mit Ausnahme eines Interners. Dies folgt Google Collections und Guava ohne eine solche Klasse. Aber ich bin auf ein Problem gestoßen, von dem ich denke, dass es ein solches Objekt verwenden könnte.
Wir haben ein Asset-Management-System in einer Renderfarm für visuelle Effekte mit mehreren hundert Prozessen, die denselben Job ausführen, der sich nur in der von ihm gerenderten Bildnummer unterscheidet. Wir haben eine Oracle-Datenbank, die alle verwendeten Ressourcen aufzeichnen muss. Anstatt Oracle mit identischen Einsätzen zu stampfen, bei denen nur einer von allen Jobs erfolgreich ist, können wir im Asset-Management-System der mittleren Ebene ein HashSet verwenden, um zu protokollieren, ob das Objekt in Oracle eingefügt wird.
Ich könnte einen Google MapMaker mit einem Ablaufdatum verwenden, aber ich möchte nicht befürchten müssen, dass das Ablaufdatum korrekt ist. Wir haben Renderings, die in Stunden und Tagen ausgeführt werden. Die Verwendung einer SoftReference mit Gleichheitsgleichheit klingt nach einem viel besseren Weg, so dass die JVM die Speicherbereinigung automatisch verwaltet.
Für andere Probleme, die ich mit einer ConcurrentHashMap mit Garbage Collection lösen möchte, würde ich eine starke Referenz in der HashMap als Schlüssel verwenden, um equals () Gleichheit und eine SoftReference als Wert zu erhalten, damit die JVM etwas sammeln kann, Aber in diesem Fall spielt der Wert keine Rolle, und ich habe keinen Wert, der in eine SoftReference eingefügt werden soll. So scheint es, als würde die Verwendung einer SoftReference mit equals () den Trick machen.
Irgendwelche anderen Vorschläge dazu?
In den meisten Fällen, in denen Sie weiche Referenzen mit Google Collections verwenden möchten, sollten Sie
anrufen %Vor%Bei starken Schlüsseln, aber weichen Werten, verwenden Nachschlagefunktionen die Gleichheit, und Schlüssel-Wert-Paare werden bei knappem Speicher zu Garbage Collections zusammengefasst.
Da es keine ConcurrentHashSet
gibt, die weiche Referenzen verwenden, gibt es nur zwei Ansätze:
1.) Ihr Ansatz mit dem ConcurrentHashMap
equals
und hashCode
in SoftReference
equals
und hashCode
greifen Sie nur auf das Objekt mit SoftReference#get
zu
SoftReference
als Schlüssel und jedes Objekt als Wert (nur null ist nicht erlaubt) containsKey
2.) Verwenden Sie ConcurrentMultimap<Integer, Set<SoftReference<RepLookupEntry>>
und verwenden Sie hashCode
als Schlüssel und eine synchronisierte Gruppe von SoftReferences
als Werte. Wenn Sie einen hashCode
Treffer erhalten, prüfen Sie den Inhalt aller SoftReferences
auf Gleichheit. Nicht sehr hübsch, stimme ich zu und schwierig zu synchronisieren.
Wenn ich in Ihrer Position wäre, würde ich SoftReferences überhaupt nicht verwenden, sondern eine ConcurrentHashMap, um starke Referenzen zu Ihren POJOs zu behalten. Jedes Mal, wenn ein neues Element eintrifft, legen Sie es auch in eine ConcurrentLinkQueue. Wenn die Warteschlange einen bestimmten Grenzwert überschreitet, beginnen Sie, Elemente aus der HashMap zu entfernen.
Ich denke, dass diese Klasse Ihre Bedürfnisse erfüllen wird:
%Vor%Dies sollte so funktionieren, dass sobald der weiche Verweis, der der Wert ist, gelöscht wird, der Wert nur noch schwach erreichbar ist und der Schlüssel aus der inneren Karte entfernt werden kann.
Tags und Links java concurrency guava concurrenthashmap