I previously come to the conclusion that if you need a SoftReference with value (equals) based equality then one had a bad design, excepting an interner from this. This is following Google Collections and Guava not including such a class. But I've come across an issue that I think could use such an object.
We have an asset management system in a visual effects render farm with 100's of processes running the same job that only differ in the frame number it renders. We have an Oracle database that needs to record all the assets used. Instead of pounding Oracle with identical inserts where only one will succeed from all the jobs, in the middle-tier asset management system we can use a HashSet to record if the object that would be inserted into Oracle.
I could use a Google MapMaker with an expiration, but I don't want to have to worry about getting the expiration correct, we have renders that run in hours and some over days. Using a SoftReference with equals equality sounds like a much better way so the JVM will manage garbage collection automatically.
For other problems that I want to solve with a ConcurrentHashMap with garbage collection, I would use a strong reference in the HashMap as the key to get equals() equality and a SoftReference as the value so the JVM can garbage collect something, but in this case, the value doesn't matter and I don't have a value to wrap in a SoftReference to put there. So it seems like using a SoftReference with equals() would do the trick.
Any other suggestions on this?
In most cases when you want to use soft references with Google Collections, you should call
MapMaker.softValues()
With strong keys but soft values, lookups will use equality and key-value pairs will be garbage collected when memory is tight.
Since there is no ConcurrentHashSet
using soft references, there are only two approaches:
1.) Your approach with the ConcurrentHashMap
equals
and hashCode
in the SoftReference
equals
and hashCode
only access the object using SoftReference#get
SoftReference
as key, and any object as value (only null is not permitted)containsKey
2.) Use a ConcurrentMultimap<Integer, Set<SoftReference<RepLookupEntry>>
and use hashCode
as key, and a synchronized set of SoftReferences
as values. When you get a hashCode
hit, then check the contents of all SoftReferences
for equality. Not very pretty, I agree and tricky to synchronize.
If I were in your position, I would not use SoftReferences at all, but rather a ConcurrentHashMap to keep strong references to your POJOs. Each time a new element arrives also put it in a ConcurrentLinkQueue. If the queue grows beyond a certain limit start removing elements from the HashMap.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With