diff --git a/libraries/stdlib/src/kotlin/collections/MapsJVM.kt b/libraries/stdlib/src/kotlin/collections/MapsJVM.kt index 468472210c6..1fef309a9d2 100644 --- a/libraries/stdlib/src/kotlin/collections/MapsJVM.kt +++ b/libraries/stdlib/src/kotlin/collections/MapsJVM.kt @@ -5,6 +5,7 @@ import java.util.LinkedHashMap import java.util.Properties import java.util.SortedMap import java.util.TreeMap +import java.util.concurrent.ConcurrentMap /** * Allows to use the index operator for storing values in a mutable map. @@ -12,6 +13,14 @@ import java.util.TreeMap // this code is JVM-specific, because JS has native set function public fun MutableMap.set(key: K, value: V): V? = put(key, value) +/** + * getOrPut is not supported on [ConcurrentMap] since it cannot be implemented correctly in terms of concurrency. + * Use [ConcurrentMap.putIfAbsent] instead, or cast this to a [MutableMap] if you want to sacrifice the concurrent-safety. + */ +deprecated("Use putIfAbsent instead or cast this map to MutableMap.") +public inline fun ConcurrentMap.getOrPut(key: K, defaultValue: () -> V): Nothing = + throw UnsupportedOperationException("getOrPut is not supported on ConcurrentMap.") + /** * Converts this [Map] to a [SortedMap] so iteration order will be in key order. * diff --git a/libraries/stdlib/test/collections/MapJVMTest.kt b/libraries/stdlib/test/collections/MapJVMTest.kt index 819936ad5d6..a02d080f149 100644 --- a/libraries/stdlib/test/collections/MapJVMTest.kt +++ b/libraries/stdlib/test/collections/MapJVMTest.kt @@ -1,5 +1,6 @@ package test.collections +import java.util.concurrent.ConcurrentHashMap import kotlin.test.* import org.junit.Test as test @@ -37,4 +38,15 @@ class MapJVMTest { assertEquals("A", prop.getProperty("a", "fail")) assertEquals("B", prop.getProperty("b", "fail")) } + + test fun getOrPutFailsOnConcurrentMap() { + val map = ConcurrentHashMap() + + fails { + map.getOrPut("x") { 1 } + } + expect(1) { + (map as MutableMap).getOrPut("x") { 1 } + } + } }