Обновить
66.03
NAUMEN
Решаем истинные задачи

Виртуальные потоки кажутся простым способом ускорить I/O. Но на Java 21 многие сталкивались со стагнацией из‑за пиннинга: когда код входит в synchronized и внутри выполняет блокирующую операцию (I/O, wait(), ожидание монитора), виртуальный поток «прибивается» к carrier‑потоку и не может отмонтироваться. Под нагрузкой это быстро исчерпывает пул carrier‑потоков и «замораживает» обработку. Часто как побочный симптом растет число соединений в CLOSE_WAIT, потому что обработчики не успевают корректно закрывать сокеты.

Что изменилось:

В JDK 24 реализован механизм, благодаря которому виртуальные потоки больше не пиннятся внутри synchronized, включая ожидание монитора и Object.wait()): JVM умеет корректно «размонтировать/перемонтировать» поток. Это почти полностью снимает главный источник проблем с Loom и в большинстве случаев избавляет от необходимости переписывать synchronized на ReentrantLock ради масштабируемости. Редкие источники пиннинга остались вне synchronized, например, JNI — их стоит искать профилированием и наблюдаемостью (JFR‑события).

Дальше — еще удобнее в JDK 25:

Scoped Values становятся финальными — надежная альтернатива ThreadLocal для передачи неизменяемого контекста без накладных расходов и утечек. Structured Concurrency остается в статусе preview и хорошо сочетается с моделью виртуальных потоков.

Что имеет смысл сделать уже сейчас без перелома архитектуры:

  1. Планировать переход на JDK 25, чтобы получить финальные Scoped Values и полный набор улучшений Loom.

  2. Запускать задачи через Executors.newVirtualThreadPerTaskExecutor() или фабрику Thread.ofVirtual() — так вы используете Loom «как задумано».

  3. Проаудировать горячие пути — убрать блокирующие вызовы из‑под synchronized, сузить критические секции. При необходимости оставлять ReentrantLock, но не рассчитывать на него как на универсальное лекарство от пиннинга.

  4. Включить наблюдаемость — отслеживать события пиннинга виртуальных потоков, рост очередей/времени ожидания и аномальный CLOSE_WAIT.

  5. Там, где сегодня используются тяжелые ThreadLocal, по возможности переносить на Scoped Values после обновления до JDK 25 и обновлять библиотеки до версий с поддержкой Loom.

Как именно работает исправление пиннинга и как лечить «больные места» рассказали в статье Виртуальные потоки в Java: эволюция, практика, подводные камни.

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии0

Публикации

Информация

Сайт
www.naumen.ru
Дата регистрации
Дата основания
Численность
1 001–5 000 человек
Местоположение
Россия