Для чего нужны виртуальные потоки в Java?
Что проверяют
Понимаете ли вы, какую проблему они решают, и знаете ли, что они не ускоряют вычисления.
Как отвечать
Виртуальные потоки (появились в Java 21) это лёгкие потоки, которыми управляет виртуальная машина, а не операционная система. Обычный поток стоит около мегабайта стека и дорогого переключения контекста, поэтому их держат сотнями. Виртуальных можно создавать миллионы.
Смысл в модели программирования. Раньше, чтобы держать много одновременных соединений, приходилось писать асинхронный код с CompletableFuture и реактивными цепочками, где теряются читаемость, стектрейсы и отладка. Виртуальные потоки позволяют писать привычный блокирующий код: поток, ожидающий ответа базы или сети, просто отцепляется от несущего потока платформы, и тот занимается другой работой.
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
urls.forEach(url -> executor.submit(() -> fetch(url)));
}Что важно назвать:
- это про ожидание, а не про счёт: вычислительную задачу виртуальный поток быстрее не сделает, там по-прежнему решают ядра;
- пул больше не нужен: поток на задачу это нормальная модель, пулы виртуальных потоков бессмысленны;
- закрепление (pinning): внутри
synchronized-блока виртуальный поток раньше не мог отцепиться от несущего, и это сводило выгоду на нет. В Java 21 это ограничение существенно, поэтому в горячих местах бралиReentrantLock; в последующих версиях проблему устранили; ThreadLocalработает, но с миллионами потоков это память, поэтому вместо него смотрят в сторону областей видимости значений;- пулы соединений к базе остаются узким местом: потоков теперь много, а соединений столько же.
Где спотыкаются
Ждут ускорения вычислительной нагрузки.
Продолжают заводить пулы потоков фиксированного размера, теряя весь выигрыш.
Считают, что реактивные библиотеки теперь не нужны совсем: они дают ещё и обратное давление, чего виртуальные потоки не решают.