Сопрограммы сами по себе не "работают" так, как это знала бы JVM. Они не что иное, как объекты в куче.
Однако контекст сопрограммы имеет право голоса, когда он позволит JVM завершить работу. Создайте свой собственный:
val threadPool = Executors.newFixedThreadPool(4)
val dispatcher = threadPool.asCoroutineDispatcher()
Теперь, если вы используете его вместо CommonPool
:
launch(dispatcher) { ... }
вы обнаружите, что JVM вообще не умирает, даже когда все задачи выполнены. Он выйдет только тогда, когда вы явно скажете
threadPool.shutdown()
Обратите внимание, однако, что executor.shutdown()
не ведет себя по отношению к сопрограммам так же, как по отношению к «классическим» задачам, которые вы передаете ему. Исполнитель будет гарантировать, что все представленные задачи будут выполнены перед завершением работы, но он не учитывает приостановленные сопрограммы.