Ruckus
10/11/2018, 8:45 PMMutex.tryLock()
always return true? Or does it just not work like ReentrantLock
?elizarov
10/11/2018, 8:53 PMfalse
if the mutex is taken and return.Ruckus
10/11/2018, 8:55 PMsuspend inline fun <T> Mutex.test(wait: Boolean, action: () -> T): T? {
return if (tryLock()) {
try {
action()
} finally {
unlock()
}
} else {
if (wait) withLock(action = action) else null
}
}
suspend fun Mutex.demo(message: String, delay: Long = 3000L, wait: Boolean = false) {
if (
test(wait) {
println("start: $message")
Thread.sleep(delay)
println("end: $message")
} == null
) {
println("skip: $message")
}
}
fun main(args: Array<String>) = runBlocking<Unit> {
val lock = Mutex()
launch { lock.demo("A", wait = false) }
delay(50)
launch { lock.demo("B", wait = false) }
delay(50)
launch { lock.demo("C", wait = false) }
}
Notice the Thread.sleep()
in demo()
. If I replace it with a delay()
it works as expected, but with Thread.sleep()
, they all wait. Is that expected?Zach Klippenstein (he/him) [MOD]
10/11/2018, 9:00 PMThread.sleep
it blocks your thread, so the runBlocking
event loop can't process any more events, so all your coroutines will block.Ruckus
10/11/2018, 9:01 PMelizarov
10/11/2018, 9:09 PMThread.sleep
inside coroutines. That would have helped to spot the problemRuckus
10/12/2018, 1:03 AMDico
10/12/2018, 4:59 AMlaunch
a coroutine with the thread used by runBlocking
. I have seen it come up as the answer to questions by confused developers multiple times.uli
10/12/2018, 5:54 AMDico
10/18/2018, 2:52 AMCoroutineScope
it will be shaded away completely by runBlocking
which does not copy any of its context.Zach Klippenstein (he/him) [MOD]
10/19/2018, 2:48 AMCoroutineScope
, you should use something like withContext
instead of calling runBlocking
- because runBlocking
is a blocking call, and making blocking calls from within a coroutine is discouraged.
The issue is the blocking call, not the fact that all coroutines happen to be dispatched to the same thread.Dico
10/19/2018, 6:53 PMwithContext
does something completely different though and is irrelevant. I'm not looking for advice for a project, I just brought up an easy little pitfall that every programmer might eventually run into. I wrote an issue in kotlinx.coroutines the other day if you want it explained better. Just to make sure it's considered.