Почему присоединение к бездействующему виртуальному потоку в статическом инициализаторе блокируется на неопределенный срок?
Примечание. Я прекрасно понимаю, что создание потоков в статических инициализаторах не рекомендуется. Тем не менее, изучение крайних случаев может дать интересную информацию и выявить нежелательное поведение или ошибки. Отсюда этот вопрос.
Экспериментируя с виртуальными потоками в Java 20, я обнаружил некоторое непоследовательное поведение при создании виртуального потока в статическом инициализаторе, который ничего не делает и присоединяется немедленно:
static {
Runnable task = () -> {};
var thread = Thread.startVirtualThread(task);
try {
thread.join();
} catch (InterruptedException e) {}
}
Здесь вызов блокируется на неопределенный срок. Это отличается от использования потока платформы, где
Вопросы:
- Хотя у меня есть общее понимание того, почему такое поведение может происходить с виртуальными потоками по сравнению с реальными потоками, задокументировано ли такое поведение или, по крайней мере, ожидается ли оно?
- Что делает использование этих встроенных лямбда-выражений noop таким особенным, что только они вызывают блокировку? Похоже, они приводят к «тупику» статической инициализации. Но почему бы этого не произошло при использовании простого
вместо?