Но есть нюанс (чтобы не выстрелить в ногу)
1. synchronized Если внутри виртуального потока выполняется старая блокировка synchronized, поток «приколачивается» к физическому ядру и перестает быть эффективным.
2. Базы данных. Чтобы выжать максимум, нужно убедиться, что драйвер СУБД поддерживает отмену запросов и неблокирующее чтение. Большинство современных драйверов (PostgreSQL, MySQL) работают отлично, но старые версии могут держать поток занятым даже при ожидании ответа от SQL.
3. Где НЕ использовать: На тяжелых вычислениях (CPU-bound задачи, например, сложные циклы без ожидания I/O). Там виртуальный поток будет постоянно занимать ядро, и выгоднее использовать обычные потоки или ForkJoinPool.