Should you check if the map containsKey before using ConcurrentMap's putIfAbsent

前端 未结 6 1910
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-07 09:02

I have been using Java\'s ConcurrentMap for a map that can be used from multiple threads. The putIfAbsent is a great method and is much easier to read/write than using stand

6条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-07 09:43

    You can use MutableMap.getIfAbsentPut(K, Function0) from Eclipse Collections (formerly GS Collections).

    The advantage over calling get(), doing a null check, and then calling putIfAbsent() is that we'll only compute the key's hashCode once, and find the right spot in the hashtable once. In ConcurrentMaps like org.eclipse.collections.impl.map.mutable.ConcurrentHashMap, the implementation of getIfAbsentPut() is also thread-safe and atomic.

    import org.eclipse.collections.impl.map.mutable.ConcurrentHashMap;
    ...
    ConcurrentHashMap map = new ConcurrentHashMap<>();
    map.getIfAbsentPut("key", () -> someExpensiveComputation());
    

    The implementation of org.eclipse.collections.impl.map.mutable.ConcurrentHashMap is truly non-blocking. While every effort is made not to call the factory function unnecessarily, there's still a chance it will be called more than once during contention.

    This fact sets it apart from Java 8's ConcurrentHashMap.computeIfAbsent(K, Function). The Javadoc for this method states:

    The entire method invocation is performed atomically, so the function is applied at most once per key. Some attempted update operations on this map by other threads may be blocked while computation is in progress, so the computation should be short and simple...

    Note: I am a committer for Eclipse Collections.

提交回复
热议问题