Alfred Lopez
06/24/2022, 5:35 PMimport kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.Default
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
class TestMutex {
val mutex = Mutex()
suspend fun createJobs() {
val job1 = CoroutineScope(Default).launch {
println("Job1")
acquireMutex("Job1")
}
val job2 = CoroutineScope(Default).launch {
println("Job2")
acquireMutex("Job2")
}
val job3 = CoroutineScope(Default).launch {
println("Job3")
acquireMutex("Job3")
}
joinAll(job1, job2, job3)
println("Delaying for a bit...")
delay(1000)
println("Done")
}
suspend fun createJobs2() {
CoroutineScope(Default).launch {
repeat(3) {
CoroutineScope(Default).launch {
println("Job$it")
acquireMutex("Job$it")
}
}
}.join()
println("Delaying for a bit...")
delay(1000)
println("Done")
}
suspend fun acquireMutex(id : String) {
if (!mutex.isLocked) {
mutex.withLock {
println("Got here...$id")
}
}
else {
println("I was directed to here...$id")
}
}
}
suspend fun main() {
val testClass = TestMutex()
println("First run...")
testClass.createJobs()
println("Second run...")
testClass.createJobs2()
}
Joffrey
06/24/2022, 5:56 PMmutex.isLocked
is not what you want, because if other coroutines have run the block and then unlocked the mutex, you can still access the block in your current coroutine.
What you could use instead is an atomic boolean for instance, which the first coroutine sets to true and others checkAlfred Lopez
06/24/2022, 7:07 PMJoffrey
06/24/2022, 7:15 PMgetAndSet
it.
Also I was talking about kotlinx-atomicfu
's atomic boolean, not the JDK's - but it should be similarAlfred Lopez
06/24/2022, 7:16 PMJoffrey
06/24/2022, 7:16 PMThe reason I’m using a mutex is to suspend the other coroutines and redirect them after the lock is releasedThen I must have missed something about your goal here. It seems what you want is that all coroutines wait for some sort of result, not just that the block is executed only once
Joffrey
06/24/2022, 7:17 PMasync
so you get a Deferred
, and then subsequent coroutines could get the same deferred and await it if needed (replace async
with launch
and Deferred
with Job
if you don't need a value)Alfred Lopez
06/24/2022, 9:50 PM