Lukasz Kalnik
07/10/2025, 4:29 PMMutableSet
where I add some elements.
Meanwhile I'm starting a coroutine with a backend call. When the call succeeds, the MutableSet
is checked if it contains the element from the backend call, and then cleared.
Adding to the set is one method, contains()
and clear()
is another method. Do I run the risk of ConcurrentModificationException
?
Code example in thread.Lukasz Kalnik
07/10/2025, 4:35 PMclass CartRepository {
val lastScannedItems = mutableSetOf<String>()
fun onNewProductScanned(id: String) {
lastScannedItems.add(id)
}
fun evaluateCart() {
CoroutineScope(SupervisorJob()).launch {
val cart = api.evaluateCart() // suspending function
if (cart.items.any { lastScannedItems.contains(it.id) }) playSound()
lastScannedItems.clear()
}
}
ephemient
07/10/2025, 4:45 PMLukasz Kalnik
07/10/2025, 4:46 PMLukasz Kalnik
07/10/2025, 4:46 PMConcurrentHashMap
?ephemient
07/10/2025, 4:53 PMCollections.newSetFromMap()
? you shouldn't encounter CME with the set thenLukasz Kalnik
07/10/2025, 4:55 PMConcurrentHashMap.newKeySet()
ephemient
07/10/2025, 4:55 PMLukasz Kalnik
07/10/2025, 4:55 PMephemient
07/10/2025, 4:55 PMLukasz Kalnik
07/10/2025, 4:55 PMLukasz Kalnik
07/10/2025, 4:55 PMLukasz Kalnik
07/10/2025, 4:56 PMLukasz Kalnik
07/10/2025, 4:57 PMLukasz Kalnik
07/10/2025, 7:12 PMfun main() {
val set = generateSequence(0) { it + 1 }
.take(1000_000)
.toMutableSet()
thread {
repeat(1000_000) {
set.contains(it)
println("Contains $it: ${set.contains(it)}")
}
}
thread {
repeat(1000_000) {
set.add(1000_000 + it)
println("Added ${1000_000 + it}")
}
}
}
Lukasz Kalnik
07/10/2025, 7:12 PMDistractic
07/15/2025, 10:32 PMDistractic
07/15/2025, 10:32 PMephemient
07/16/2025, 8:04 PMjava.util.HashSet
(which delegates to java.util.HashMap
) and its contains
method never throws CME. it looks like it might NPE if you got lucky enough with concurrent operations, but it's rather tricky to hitephemient
07/16/2025, 8:09 PMLukasz Kalnik
07/17/2025, 7:43 AMLukasz Kalnik
07/17/2025, 7:43 AMcontains()
ever change.