Почему присоединение к бездействующему виртуальному потоку в статическом инициализаторе блокируется на неопределенный срок?

Примечание. Я прекрасно понимаю, что создание потоков в статических инициализаторах не рекомендуется. Тем не менее, изучение крайних случаев может дать интересную информацию и выявить нежелательное поведение или ошибки. Отсюда этот вопрос.

Экспериментируя с виртуальными потоками в Java 20, я обнаружил некоторое непоследовательное поведение при создании виртуального потока в статическом инициализаторе, который ничего не делает и присоединяется немедленно:

      static {
    Runnable task = () -> {};
    var thread = Thread.startVirtualThread(task);
    try {
        thread.join();
    } catch (InterruptedException e) {}
}

Здесь вызов блокируется на неопределенный срок. Это отличается от использования потока платформы, гдевозвращается немедленно. Поведение блокировки также очень чувствительно к . Блокировки нет, еслиявляется экземпляром вместо лямбды. Также нет никакой блокировки, если, где.

Вопросы:

  • Хотя у меня есть общее понимание того, почему такое поведение может происходить с виртуальными потоками по сравнению с реальными потоками, задокументировано ли такое поведение или, по крайней мере, ожидается ли оно?
  • Что делает использование этих встроенных лямбда-выражений noop таким особенным, что только они вызывают блокировку? Похоже, они приводят к «тупику» статической инициализации. Но почему бы этого не произошло при использовании простоговместо?

0 ответов

Другие вопросы по тегам