Edit (Aug. 2012):
It turns out that currently the best solution are probably Guava 13.0's Cache
classes, explained on Guava's Wiki - that's what I'm going to use.
It even supports building a SoftHashMap
(see CacheBuilder.newBuilder().softKeys()
), but it is probably not what you want, as Java expert Jeremy Manson explains (below you'll find the link).
Not that I know of (Nov. 2008), but you kind find some implementation of SoftHashMap
on the net.
Like this one: SoftHashMap
or this one.
Edit (Nov. 2009)
As Matthias mentions in the comments, the Google Guava MapMaker does use SoftReferences:
A ConcurrentMap
builder, providing any combination of these features:
- soft or weak values,
- timed expiration, and
- on-demand computation of values.
As mentioned in this thread, another JSR166y candidate:
jsr166y.ConcurrentReferenceHashMap
It provides an alternative concurrent reference map to the Google implementation (which relies on a background thread to evict entries)
Edit (August 2012)
The Google implementation uses a background thread only when timed expiration of entries is requested. In particular, it simply uses java.util.Timer
, which is not so intrusive as having a separate background thread.
Jeremy Manson recommends, for any cache, using this feature to avoid the dangers of SoftReference:
http://jeremymanson.blogspot.de/2009/07/how-hotspot-decides-to-clear_07.html
There's another implementation from Apache Commons, namely org.apache.commons.collections.map.ReferenceMap; it does not support timed removal, but it does support choosing whether keys should be compared by identity or by equality. Moreover, this implementation is not concurrent - it can be made synchronized, but that works less well under accesses from multiple threads.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…