I want to simulate the following behaviour using c...
# coroutines
c
I want to simulate the following behaviour using coroutines:
Copy code
val executor = Executors.singleThreadExecutor()

fun oneAtATime(workToDo: Boop) {
   return executor.submit {
      doSomethingWIthThe(workToDo)
   }.get()
}
Where
oneAtATime(...)
may be invoked by multiple threads, but will only allow one operation at a time due to the single thread executor.
is it as simple as creating a new coroutineScope with a single thread executor
.asCoroutineDispatcher
?
j
You could indeed use
withContext()
and pass a single thread dispatcher (no need for a coroutine scope, just a dispatcher). However, if what you want is mutual exclusion, you should probably just use a
Mutex
and protect the piece of code with
mutex.withLock { ... }
c
cheers Joffrey, I'll give it a go! 🤜 💥 🤛
e
is that structure actually what you want? consider an alternative, if you have an appropriate owning scope,
Copy code
private val workQueue = MutableSharedFlow<Boop>()
private val worker = scope.launch {
    workQueue.collect { workToDo ->
        doSomethingWithThe(workToDo)
    }
}
suspend fun oneAtATime(workToDo: Boop) {
    workQueue.emit(workToDo)
}
which makes it more obvious that the work is being processed sequentially and uniformly, without requiring additional locking
j
For some reason I was assuming a result was expected by
oneAtATime()
but you're right, in the OP there is no such result, which makes it possible to just enqueue asynchronously
e
unless the function is expected to block or has a non-
Unit
return type which is missing in the example, in which case your proposal is better
d
How about using
limitedParallelism
on a dispatcher of your choice? https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-dispatcher/limited-parallelism.html
Copy code
val dispatcher = Dispatchers.Default.limitedParallelism(1)

suspend fun oneAtATime(workToDo: Boop) = withContext(dispatcher) {
  doSomethingWIthThe(workToDo)
}
c
oooo limited parallelism looks like a nice approach, that's super duper obvious! Thanks all
e
whether limitedParallelism works depends on what your
doSomethingWithThe()
function does. if it requires parallelism internally, that's a problem, but if it's just a blocking call then you're fine
u
Be aware though… Single threaded dispatchers and limited parallelism just limit … well … parallelism. If doSomethingWIthThe(workToDo) is suspending, multiple coroutines could still be suspended and resumed concurrently.