christophsturm
07/09/2021, 12:02 PMenleur
07/09/2021, 12:14 PMenleur
07/09/2021, 12:14 PMmutableMapOf<String, Int?>().apply {
getOrPut("b") { null}
} // {b=null}
mutableMapOf<String, Int?>().apply {
computeIfAbsent("b") { null}
} // {}
dmitriy.novozhilov
07/09/2021, 12:25 PM/**
* Concurrent getOrPut, that is safe for concurrent maps.
*
* Returns the value for the given [key]. If the key is not found in the map, calls the [defaultValue] function,
* puts its result into the map under the given key and returns it.
*
* This method guarantees not to put the value into the map if the key is already there,
* but the [defaultValue] function may be invoked even if the key is already in the map.
*/
public inline fun <K, V> ConcurrentMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
// Do not use computeIfAbsent on JVM8 as it would change locking behavior
return this.get(key)
?: defaultValue().let { default -> this.putIfAbsent(key, default) ?: default }
}
christophsturm
07/09/2021, 12:58 PMdmitriy.novozhilov
07/12/2021, 8:05 AMConcurrentHashMap.putIfAbsent
takes a lock even if map contains key
. So getOrPut
provides a fastpath without taking that lock