Can someone explain to me when it is useful to use

2019-05-02 02:41发布

问题:

I have read many people really like the MapMaker of Google Guava (Collections), however I cannot see any good uses of it.

I have read the javadoc, and it says that it behaves like ConcurrentHashMap. It also says new MapMaker().weakKeys().makeMap() can almost always be used as a drop-in replacement for WeakHashMap.

However, reading the javadocs of ConcurrentHashMap and WeakHashMap makes me wonder when it is useful to use it? It seems to me that you cannot have a guarantee that whatever you put in the map will be there, or have I misunderstood?

回答1:

...and that's somewhat the point of it. Weak references are useful, if you don't want to (or cannot afford to) retain an object indefinetly in memory. Consider the following use case: you need to associate information with classes. Now, since you are running in an environment, where classes might get reloaded (say, a Tomcat, or OSGi environment), you want the garbage collector to be able to reclaim old versions of a class as soon as it deems safe to do so.

An initial attempt to implement this, might look like

class ClassAssoc {
    private final IdentityHashMap<Class<?>,MyMetaData> cache = new ...;
}

The problem here is: this would keep all classes in the cache member forever (or at least, unless they are manually removed), forcing the garbage collector to retain them indefinitly, including everything referenced from the class (static member values, class loader information, ...)

By using weak references, the garbage collector can reclaim old version of the class as soon as no other references to it (usually instances) exist. On the other hand: as long as such references exist, the value is guaranteed to be also reachable from the weak reference object, and thus, is a valid key in the cache table.

Add concurrency and other atrocities to the picture, and you are at what MapMaker optionally also provides...



回答2:

The thing about MapMaker is that there are many options for the kind of map you build, which enables those maps to serve many purposes.

  • Dirk gives a good example of a use for weak keys.
  • Soft values are useful for caching, as you can cache values in the map without worrying about running out of memory since the system is free to evict entries from the cache if it needs memory.
  • You can choose to have entries expire after a certain amount of time. This is also useful for caching, since you may want certain data cached for a specific period of time before doing an expensive operation to update it.
  • One of my favorite things is making a computing map. A computing map uses a Function<K, V> to automatically retrieve the value associated with a given key if it isn't already in the map. This combines well with soft values and/or expiration times. After an entry is evicted by the map (due to memory demand or expiration), the next time the value associated with that key is requested it will automatically be retrieved and cached in the map once more.


回答3:

A WeakHashmap entry will be kept in the map while someone (other than the map) is referencing the entry. If nobody else thant the map is keeping a reference on the entry, then the entry can be removed on a next GC run.



回答4:

ConcurrentHashMap is a Map which may be safely used in multi-threading environment. It is better than synchronized version of regular Map because concurrency means that different threads are often available to access this map without blocking.