From Java 5 and onwards, we have access to some atomic thread safe structures, that are still useful with coroutines:
import java.util.concurrent.atomic.AtomicInteger
fun main(args: Array<String>) = runBlocking {
val counter = AtomicInteger(0)
val time = measureTimeMillis {
repeatInParallel(1_000_000) {
counter.incrementAndGet()
}
}
println("counter = ${counter.get()}")
println("time = $time")
}
AtomicInteger gives us many atomic operations that are thread safe. There are more thread safe structures such as other atomic primitives and concurrent collections.