Java 为什么ExecutorService在从类加载器线程启动时不处理提交的任务?

Java 为什么ExecutorService在从类加载器线程启动时不处理提交的任务?,java,multithreading,executorservice,classloading,Java,Multithreading,Executorservice,Classloading,我有一个类Singleton(本例简化) 此构造永远不会从ExecutorService.awaitTermination返回(预计在1秒多一点后返回) 如果我切换到标记为“working alternative”的代码,在Singleton中注释它(并注释掉另一个),注释掉static块,代码将按预期执行(method1和method2被调用,并根据输出以相反的顺序返回) 由于“工作替代方案”可以防止出现问题,我可以接受它,因此我正在寻找对这种行为的解释 我打算使用Class.forName而

我有一个类
Singleton
(本例简化)

此构造永远不会从
ExecutorService.awaitTermination
返回(预计在1秒多一点后返回)

如果我切换到标记为“working alternative”的代码,在
Singleton
中注释它(并注释掉另一个),注释掉
static
块,代码将按预期执行(
method1
method2
被调用,并根据输出以相反的顺序返回)

由于“工作替代方案”可以防止出现问题,我可以接受它,因此我正在寻找对这种行为的解释


我打算使用
Class.forName
而不是
Singleton.init
来为
Singleton
添加更多的静态初始化任务,而无需考虑它们是否被预初始化例程覆盖。我同意,整个设置并不理想。

您走错了方向。首先,不要在初始化类时进行繁重的计算。在类初始化完成之前,类方法的调用受到限制。其思想不是向类方法显示尚未初始化的变量。只能执行直接从静态初始值设定项调用的方法,否则将阻止它们。在您的例子中,来自并行任务的
method1
method2
调用被阻止

通常,尽可能避免使用静态变量。而是创建对象的实例。对于给定的情况,创建Singleton类的实例,将所有变量从静态字段转换为实例字段

最后,不要只运行线程来调用

  thread.start();
  thread.join();

最好直接调用传入线程的方法,因为
Runnable

您正在朝错误的方向移动。首先,不要在初始化类时进行繁重的计算。在类初始化完成之前,类方法的调用受到限制。其思想不是向类方法显示尚未初始化的变量。只能执行直接从静态初始值设定项调用的方法,否则将阻止它们。在您的例子中,来自并行任务的
method1
method2
调用被阻止

通常,尽可能避免使用静态变量。而是创建对象的实例。对于给定的情况,创建Singleton类的实例,将所有变量从静态字段转换为实例字段

最后,不要只运行线程来调用

  thread.start();
  thread.join();

最好直接调用作为
Runnable

传递到线程中的方法。这有点意味着JRE不会抛出异常,而是永远阻塞。由于死锁,永远阻塞。死锁不容易发现。这有点意味着JRE不会抛出异常,而是永远阻塞。因为死锁而永远阻塞。死锁不容易被发现。
  thread.start();
  thread.join();