Вы не просто начинаете другой поток - вы присоединяетесь к . Этот новый поток должен дождаться полной инициализации StaticInitializer
, прежде чем он сможет продолжить, потому что он пытается установить поле state
... и инициализация уже выполняется, поэтому он ждет. Тем не менее, он будет ждать вечно, потому что эта инициализация ожидает завершения нового потока. Классический тупик.
См. Раздел Спецификация языка Java 12.4.2 для получения подробной информации о том, что входит в инициализацию класса. Важно отметить, что инициализирующий поток будет «владеть» монитором для StaticInitializer.class
, но новый поток будет ожидать получения этого монитора.
Другими словами, ваш код немного похож на этот код не инициализатора (исключена обработка исключений).
final Object foo = new Object();
synchronized (foo)
{
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (foo) {
System.out.println("In the new thread!");
}
});
t1.start();
t1.join();
});
Если вы понимаете, почему этот код блокируется, то для вашего кода это в основном то же самое.
Мораль не в том, чтобы много работать в статических инициализаторах.