JEP 444: Виртуальные потоки

JEP 444: Виртуальные потоки


Март 28, 2024


JEP 444: Виртуальные потоки был финально внедрен в JDK 21 и его дистрибутивы, включая Axiom JDK 21. Также эта фича появилась в новой версии сервера Java-приложений Libercat. Она разрабатывается для Java с 2017 года в рамках Проекта Loom, цель которого — повышение производительности многопоточных Java приложений посредством более эффективного использования аппаратных ресурсов. Более того, разработчикам будет гораздо удобнее разрабатывать и поддерживать многопоточные приложения с помощью встроенных в JDK и понятных API.

Для чего нужны виртуальные потоки в Java?

Проблема

Многопоточность — разделение процесса на несколько параллельно работающих потоков — существует в Java давно. Каждый поток выполняет свои задачи независимо от других, при этом можно получить стек-трейс каждого потока для удобной отладки и профилирования. С потоками можно работать двумя способами. Первый заключается в назначении отдельного потока на каждый запрос. С такими потоками легко работать, но так как они привязываются к потокам операционной системы, их количество ограничено. Поэтому для масштабирования приложения разработчики иногда пользуются методами асинхронного программирования. В данном случае потоки не закрепляются пожизненно за запросом, но возвращаются в пул для выполнения других запросов. Таким образом, приложение может выполнять больше задач одновременно без увеличения количества потоков. Но асинхронный код сложнее писать, а поведение приложения — профилировать.

Решение

Виртуальные потоки Java позволяют разработчикам достичь две цели: значительно увеличить количество потоков, при этом сохранив преимущества синхронного программирования (понятный код, удобная отладка и профилирование). Виртуальные потоки не привязаны к потокам ОС на протяжение всего жизненного цикла кода. Они занимают поток ОС только на время выполнения определенных вычислений, т.е. сразу несколько виртуальных потоков могут одновременно работать с одним потоком ОС.

Количество виртуальных потоков практически не ограничено. В условиях, когда программе нужно выполнить одновременно 10 000 задач, можно создать только 200 потоков ОС, что дает пропускную способность 200 запросов/с. При этом можно создать 10 000 виртуальных потоков, и тогда пропускная способность увеличится до 10 000 запросов/с. С увеличением количества задач можно увеличивать и количество виртуальных потоков, что позволяет эффективно масштабировать приложение без увеличения нагрузки на аппаратное обеспечение.

Но еще виртуальные потоки легко профилировать, координировать и отлаживать. Отладчики и профайлеры JDK могут с легкостью отслеживать виртуальные потоки, анализировать стек-трейсы и определять, с каким потоком связано то или иное событие. Поскольку виртуальные потоки входят в JDK, разработчики могут использовать ForkJoinPool для распределения работы потоков и запуска кода без изменений. Более того, необходимость в пуле виртуальных потоков отпадает, так как пулы потоков используются в условиях дороговизны ресурсов, а виртуальные потоки не требуют серьезные ресурсных затрат.

Сопутствующие изменения

Для приведения кода JDK в соответствие с новым функционалом были обновлены следующие компоненты:

  • java.lang.Thread
  • Thread-local variables
  • java.util.concurrent
  • Networking
  • java.io
  • Java Native Interface (JNI)
  • Debugging (JVM TI, JDWP, and JDI)
  • JDK Flight Recorder (JFR)
  • Java Management Extensions (JMX)
  • java.lang.ThreadGroup

Появление Virtual Threads повлияло на архитектуру и код других возможностей, появившихся в Java 21, например, структурной многопоточности (JEP 453) и современной замены для thread locals, которая называется scoped values (JEP 446). Обе перечисленные фичи находятся в статусе предварительной оценки (preview), но в будущих версиях Java должны существенно повлиять на то, как обычные прикладные программисты пишут многопоточный код.

Кроме того, разработчики OpenJDK провели множество регрессионных тестов перед релизом JDK 21, чтобы убедиться в отсутствии влияния на производительность Java приложений. Основные риски внедрения нового JEP связаны с совместимостью с существующими API. С перечнем рисков и ограничений вы можете ознакомиться на странице JEP (на английском языке).

Виртуальные потоки хорошо сочетаются со структурной многопоточностью, новым API для управления работой потоков на основании четких взаимосвязей между ними. Об этих и других новых фичах вы можете почитать в нашей статье о JDK 21.

Важность проекта Loom для Java разработчиков

JEP 444 — это большой шаг на пути к интеграции проекта Loom в код JDK. Проект будет полезен всем разработчикам, работающим с многопоточными приложениями, поскольку он обеспечивает удобное и эффективное масштабирование в рамках JVM без использования сторонних библиотек и фреймворков.

Подытоживая, сложно переоценить важность Loom и Virtual Threads для Java. Здесь мы поделились ключевой информацией о новом функционале, но сам проект требует более подробного обсуждения в отдельной статье. Подпишитесь на наш Telegeam-канал, чтобы не пропустить ее и оставаться в курсе новостей из мира Java!

Author image

Александр Дроздов

Инженер по РБПО и информационной безопасности Axiom JDK

Axiom JDK info@axiomjdk.ru Axiom JDK logo Axiom Committed to Freedom 199 Obvodnogo Kanala Emb. 190020 St. Petersburg RU +7 812-336-35-67 Axiom JDK 199 Obvodnogo Kanala Emb. 190020 St. Petersburg RU +7 812-336-35-67