Есть ли способ получить поведение FixedTreadPool с помощью сопрограмм?

Есть ли способ получить то же поведение, что и фрагмент кода ниже, но используя сопрограммы?

Обновленный фрагмент кода:

fun main(args: Array<String>) = runBlocking { val executor = Executors.newFixedThreadPool(50) log.info("Start") val jobs = List(300) { executor.submit { log.info("worker #$it started") sleep(1000L) log.info("worker #$it done") } } jobs.forEach { it.get() } executor.shutdown() log.info("All done!") } 

Как я могу запустить 300 заданий с коэффициентом параллелизма == 50, но без создания 50 реальных потоков?

Обновление 2: Решение

После прочтения руководства Coroutines еще раз, я обнаружил, что пример Fan-out – это именно то, что я искал. Таким образом, мой пример будет выглядеть следующим образом:

 fun produceTasks() = produce { for (taskId in 1..300) { send( async(start = CoroutineStart.LAZY) { delay(1000) // simulate long work taskId } ) } close() } fun launchWorker(index: Int, channel: ProducerJob<Deferred<Int>>) = launch { channel.consumeEach { val result = it.await() log.info("Worker #$index done task #$result") } } fun main(args: Array<String>) = runBlocking { val tasks = produceTasks() val workers = List(50) { launchWorker(it + 1, tasks) } workers.forEach { it.join() } log.info("Done") } 

Вместо использования контекста CommonPool в качестве аргумента для разработчиков coroutine, таких как launch , вы также можете определить свой собственный контекст, в котором выполняются сопрограммы. Для фиксированного пула он может выглядеть следующим образом:

 fun main(args: Array<String>) = runBlocking { val mtContext = newFixedThreadPoolContext(3, "mtPool") val jobs = List(50) { launch(mtContext) { // use it instead of CommonPool in this sample and below println("${Thread.currentThread()}: worker #$it started") delay(1000L) println("${Thread.currentThread()}: worker #$it done") } } jobs.forEach { it.join() } mtContext.close() }