(java || kotlin) && devOps
369 subscribers
6 photos
1 video
6 files
306 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Всем привет!

Есть такая фраза - все новое - это хорошо забытое старое. Еще есть тезис, что все развивается по спирали.
К чему это я?)

Если вы имеете отношение к миру Java - вы наверняка слышали про virtual threads. https://openjdk.org/jeps/425
Для начала немного теории. В ОС есть процессы - это запущенная программа или фоновый процесс. У каждого процесса может быть несколько потоков, которыми также управляет ОС. Поток занимает ресурсы - как минимум память, а при выполнении - еще и процессорное время. Поток может блокироваться - ожидать какого-то события для продолжения операции. Больше того - не ошибусь, если скажу, что в большинстве сервисов время блокировки >=50% общего времени выполнения потока.
При блокировке расходуется только память и емкость пула потоков, из которого этот поток был взят (процессорное время - нет). Особенно опасна блокировка тогда, когда она массовая - тогда пул быстро заканчивается, и все новые запросы к приложению отбиваются. Еще более опасна, если поток не из пула, например, он обслуживает UI или это основной поток выполнения программы - метод main, т.к. тогда блокируется приложение целиком.

Виртуальные потоки призваны снизить остроту этой проблемы. Как именно?
Виртуальный поток - это как бы обычный поток, вот пример его создания:

Thread thread = Thread.ofVirtual().start(() -> System.out.println("Hello"));

того же класса Thread https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Thread.html
Но если обычный поток мапится один к одному на поток ОС, то виртуальные управляются JVM и работают в рамках одного системного потока, т.наз. carrier потока. Выглядит это так: https://belief-driven-design.com/images/2023/2023-10-05-java-21-virtual-threads-scheduler.webp
К чему приводит такой подход?
1) виртуальные потоки более "дешевые" в плане памяти, т.к. управление идет на уровне JVM
2) при блокировке виртуального потока поток ОС не блокируется, может выполнять полезную работу, например, обрабатывать запросы новых пользователей
3) можно использовать обычные блокирующие конструкции языка, без CompletableFuture и Reactive кода, которые проще создавать и что наверное более важно - проще отлаживать.

Но вернусь к новому и старому)

В Java 1.1 появились Green Threads https://en.wikipedia.org/wiki/Green_thread
Что это за зверь такой? А примерно тоже самое - создаем несколько потоков на уровне JVM, все они средствами JVM мапятся на один поток ОС. Зачем? Был 1997 год, памяти было мало, создавать потоки было очень дорого. Потом память подешевела, проблема казалось бы ушла. В Java 1.3 green threads убрали.
Потом памяти стало еще больше, но число клиентских запросов и сложность кода выросли еще сильнее, чем память. И в 2021 году к идее вернулись.

P.S. Потоки, управляемые виртуальной машиной - стандартная штука для языков, у которых эта виртуальная машина есть. У них есть общее название - fibers. Пример - goroutines в Go.

#threads #concurrency #java #go