In this code:
private suspend fun doSthSingleThreaded(){
coroutineScope {
//Coroutine 1
launch {
//do sth that will suspend
}
//Coroutine 2
launch {
//Do sth else that will suspend too
}
}
}
Is there a way that I can make these 2 Coroutines behave like they are sharing the underlying thread? this is how I want it to work ( I want to adjust the code in a way that they both use threadA):
EDIT: This is Y I want to do this: I have a SharedFlow that is somehow a single source of truth for all the data I receive from a serial port.
val hotFlow = SharedFlow<String> //buffer = ALot, replay = 0
Any time I write anything to that port I read it's answer from here. like this:
port.writeSth()
val answer = hotFlow.first {it == "OK" || it == "ERROR"}
if (answer == "OK") return
//process error
The problem with the code above (with replay = 0) is that HotFlow sometimes returns a response and then returns sth else so quickly that I am not able catch my answer!
Why replay = 0? All the different commands that I write to this port have the answer "OK" or "ERROR", and the port does not return anything that says what command this answer belongs to. So if replay != 0:
port.writeSth()
val portCache = hotFlow.replay
//Now how do I know if the last item is my answer or I should still wait?
so I thought maybe I can:
launch {
val answer = hotFlow.first{it == "OK" || it == "ERROR" }
//process answer
}
launch {
port.writeSth()
}
order of execution:
You can get a single thread bound coroutine dispatcher with newSingleThreadContext, but please be wary:
A dedicated thread is a very expensive resource. In a real application it must be either released, when no longer needed, using the close function, or stored in a top-level variable and reused throughout the application.
If instead you only need to limit parallelism you can use limitedParallelism instead: Dispatchers.Default.limitedParallelism(1)
. This will not guarantee that the coroutines will always use the same thread, only that at most one coroutine is executed at the same time.
private suspend fun doSthSingleThreaded() {
val confined = newSingleThreadContext("My Thread")
// or
// val confined = Dispatchers.Default.limitedParallelism(1)
withContext(confined) {
//Coroutine 1
launch {
//do sth that will suspend
}
//Coroutine 2
launch {
//Do sth else that will suspend too
}
}
}