Информация об изменениях

Сообщение Re[5]: Киллер фича JDK 21 - virtual threads от 09.05.2023 23:25

Изменено 10.05.2023 0:44 m2user

Re[5]: Киллер фича JDK 21 - virtual threads
m>> Погодите, а как же cancellation?
·>Банальный interrupt() например, доступный ещё с java 1.0.
·>Ну или Future.cancel() или любой другой паттерн.

И как это применимо к классическим локам без переписывания кода?
Если мне нужно отменить ожидание на lock, то придется его в VirtualThread обернуть?

·>Просто представь себе как бы ты писал простой, читабельный код, если ты знаешь, что там будет максимум десяток тредов. И представь себе, что этот код потом можно отмасштабировать на миллионы.


m>> Вот в C# например я не могу использовать обычную lock секцию с async/await и вместо этого вынужден делать крит. секцию на основе SemaphoreSlim, где есть асинхронный wait и Cancellation.

·>Именно. Вот об этом гне и говорю. Есть Wait, и ещё нужен AsyncWait и ещё с CancellationToken . Итого намножилось аж 12 методов. И это приходится размазывать повсюду.

Так и VirtualThread тоже самое.
Вместо await Task будет VirtualThread.join

Как в примере, из статьи на которую ты ссылался
@SneakyThrows
static void concurrentMorningRoutine() {
  var bathTime = bathTime();
  var boilingWater = boilingWater();
  bathTime.join();
  boilingWater.join();
}
Re[5]: Киллер фича JDK 21 - virtual threads
m>> Погодите, а как же cancellation?
·>Банальный interrupt() например, доступный ещё с java 1.0.
·>Ну или Future.cancel() или любой другой паттерн.

И как это применимо к классическим локам без переписывания кода?
Если мне нужно отменить ожидание на lock, то придется его в VirtualThread обернуть?

Дополнение:
Согласно документации
Thread.interrupt не действует на обычную synchronized секцию, и не на любой Lock

Further, the ability to interrupt the ongoing acquisition of a lock may not be available in a given Lock class

Кроме того, согласно https://openjdk.org/jeps/444

There are two scenarios in which a virtual thread cannot be unmounted during blocking operations because it is pinned to its carrier:

When it executes code inside a synchronized block or method, or
When it executes a native method or a foreign function.


В JEP предлагают заменить synchronized block на ReentrantLock, т.е. придется править код.


·>Просто представь себе как бы ты писал простой, читабельный код, если ты знаешь, что там будет максимум десяток тредов. И представь себе, что этот код потом можно отмасштабировать на миллионы.


m>> Вот в C# например я не могу использовать обычную lock секцию с async/await и вместо этого вынужден делать крит. секцию на основе SemaphoreSlim, где есть асинхронный wait и Cancellation.

·>Именно. Вот об этом гне и говорю. Есть Wait, и ещё нужен AsyncWait и ещё с CancellationToken . Итого намножилось аж 12 методов. И это приходится размазывать повсюду.

Так и VirtualThread тоже самое.
Вместо await Task будет VirtualThread.join

Как в примере, из статьи на которую ты ссылался
@SneakyThrows
static void concurrentMorningRoutine() {
  var bathTime = bathTime();
  var boilingWater = boilingWater();
  bathTime.join();
  boilingWater.join();
}