Недавно я узнал что в новых версиях Java появилась штука, похожая на корутины - виртуальные потоки:
// специальный пул виртуальных потоков
var executor = Executors.newVirtualThreadPerTaskExecutor()
try (executor) {
// создаем 50к виртуальных потоков
IntStream.range(0, 50_000).forEach(i -> {
executor.submit(() -> {
...
});
});
}
Как видите создание виртуальных потоков не такая дорогостоящая операция, кстати у корутин был аналогичный пример в доке, где еще говорилось что корутины это легковесные потоки:
fun main() = runBlocking {
// запускаем 50к корутин
repeat(50_000) {
launch {
...
}
}
}Безусловно виртуальные потоки далеки от того функционала, который могут предоставить корутины, но мне было интересно что они из себя представляют, вот несколько фактов о них:
1) Виртуальный поток наследует класс
Thread, сохраняя общий интерфейс, но переопределяя метод Thread.start(), где больше нет вызова нативного метода - классический Thread создается и запускается системой.2) Виртуальный поток выполняется на некотором пуле потоков - в корутинах под капотом тоже используются пулы, только над ними есть такая абстракция как
CoroutineDispatcher, например: Dispatchers.IO.3) Иерархия виртуальные потоков не такая мощная по функционалу как в корутинах - родитель только предоставляет пул дочерним виртуальным потокам.
4) Виртуальные потоки отменяются абсолютно также как и классические - с помощью методов
Thread.interrupt() и Thread.isInterrupted() или через Boolean флаги.5) Исключения в виртуальных потоках обрабатываются также как и в обычных - если исключение необработанно поток просто завершится.
По итогу мы имеем такой же интерфейс, как и у обычных потоков
Thread, только виртуальные потоки не создаются системой, а являются обыкновенными объектами, выполняющими свои задачи на пуле классических потоков Thread.Пишите в комментах ваше мнение и всем хорошего кода!