Когда вы программируете с использованием Kotlin сопрограмм или Java виртуальных потоков (после Loom), вы получаете упреждающее планирование из ОС.
Следуя обычной практике, задачи, которые не выполняются заблокированные (т. е. им нужен ЦП), мультиплексируются по реальным потокам ОС в диспетчере Kotlin по умолчанию или Java ForkJoinPool. Эти потоки ОС планируются операционной системой с упреждением.
Однако, в отличие от многопоточности в старом стиле, задачи не назначаются потоку, когда они заблокированы в ожидании ввода-вывода. Это делает никакой разницы с точки зрения вытеснения, поскольку задача, ожидающая ввода-вывода, в любом случае не может вытеснить другую запущенную задачу.
Что вы не get при программировании с помощью сопрограмм - это упреждающее планирование большого количества задач одновременно. Если у вас есть много задач, требующих ЦП, то первые N будут назначены реальному потоку, а ОС будет их разрезать по времени. Остальные будут ждать в очереди, пока они не будут выполнены.
Но в реальной жизни, когда у вас есть 10000 задач, которые должны быть одновременно интерактивные , они связаны с задачами ввода-вывода. . В среднем не так много ресурсов, которым требуется процессор одновременно, поэтому количество реальных потоков, которые вы получаете от диспетчера по умолчанию или ForkJoinPool, достаточно. • 1017 интерактивный, ну, тогда вам все равно будет грустно, потому что квантование времени не обеспечит очень плавного взаимодействия.