Synchronized And Coroutines
Compiler prevents some combined usage
From Compiler Prevents Using Suspension in Synchronized Blocks
Go to text ā
Good news: compiler prevents using synchronized
with co-routine suspension.
GT-Sandbox-Snapshot
Code
package com.glassthought.sandbox
import kotlinx.coroutines.*
var counter = 0
val lock = Any()
suspend fun incrementCounter() {
synchronized(lock) {
val current = counter
// Attempt to use a delay inside synchronized block
// Compiler will not allow this with error:
//
// "The 'delay' suspension point is inside a critical section"
delay(100)
counter = current + 1
}
}
fun main() = runBlocking {
val jobs1 = List(1000) {
launch(Dispatchers.Default) {
incrementCounter()
}
}
val jobs2 = List(1000) {
launch(Dispatchers.IO) {
incrementCounter()
}
}
jobs1.forEach { it.join() }
jobs2.forEach { it.join() }
println("Final counter value: $counter")
}
Command to reproduce:
gt.sandbox.checkout.commit 457aa7534d22088c0603 \
&& cd "${GT_SANDBOX_REPO}" \
&& cmd.run.announce "_gt_no_op_for_snapshotting_with_printout"
Recorded output of command:
No command ran. Just snapshot.
Children