首页 > 解决方案 > 无法在静态工作流/块中使用 ExecutorService 执行任务

问题描述

我正在开发一个使用工作流加载一次性缓存的模块static。缓存加载通常需要大约一个小时。为了提高性能,我正在考虑使用线程池并行运行这些任务。这是示例代码。

应用程序启动类:

public class AppStart {
    public static void main(String[] args) {
        Cache.isValid();  // this will trigger the static workflow
        // ...
    }
}

缓存加载器类:

public class Cache {

    static {
        System.out.println("Static block initialization started!");
        initialize();
        System.out.println("Static block initialization finished!");
    }

    public static void initialize( ) {
        System.out.println("initialize() started!");
        ExecutorService executorService = Executors.newSingleThreadExecutor(); // will replace with fixedThreadPool
        Future<String> future = executorService.submit(() -> "Hello world!");
        System.out.println("Retrieve the result of the future");
        String result = null;
        try {
            result = future.get();
            System.out.println(result);
        } catch( InterruptedException e ) {
            e.printStackTrace();
        } catch( ExecutionException e ) {
            e.printStackTrace();
        }
        executorService.shutdown();
    }

    public static boolean isValid( ) {
        return true;
    }
}

然而,在上面的例子中,阻塞操作future.get被永远阻塞了,尽管它只做一个微不足道的任务来返回一个字符串。

我也尝试过使用ForkJoinPool,我没有运气。

jconsole我使用无法检测到任何死锁来监视线程。为什么它的行为很奇怪?

标签: javafutureexecutorserviceforkjoinpool

解决方案


这似乎是预期的行为。这是一个经典的类初始化死锁。

使用依赖于类的静态初始化完成的 Runnable 启动一个新线程。future.get()反过来,由于方法调用,该类正在等待 Runnable 完成。静态初始化正在等待线程完成,线程正在等待静态初始化完成。

JLS:: 类初始化提供了类初始化过程的详细信息。

我想知道为什么jconsole无法检测到死锁


推荐阅读