ExecutorService Submit() 无法按预期使用 lambda 版本的 Callable

Kid*_*ler 5 java future callable executorservice threadpoolexecutor

我正在尝试编写一种机制,可以同时加载一些模型(使用 ExecutorService)并在所有模型完成后检索它们的结果:

List<Future<Model>> modelFutures = new LinkedList<Future<Model>>();
ExecutorService executor = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE);
List<Model> models = new ArrayList<Model>();
for (ClassifierConfig classifierConfig : classifiers) {
    try {
        final String modelFileName = classifierConfig.name + ".model";
        modelFutures.add(executor.submit(new InitModelTask(MODELS_LOCAL_DIR + SEP + modelFileName)));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

for (Future<Model> modelFuture : modelFutures) {
    try {
        models.add(modelFuture.get(MAX_REQUEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
    } catch (Exception e) {
        System.out.println("Timeout occurred when loading models ");
    }
}
executor.shutdown();
return models;
Run Code Online (Sandbox Code Playgroud)

任务类如下:

public class InitModelTask implements Callable<Model> {

    private String modelFileName;

    public InitModelTask(String modelFileName) {
        this.modelFileName = modelFileName;
    }

    @Override
    public Model call() throws Exception {
        return WekaModuler.loadModel(modelFileName, Model.class);
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码有效。

但是,我想通过以下方式调用执行器的方法来摆脱InitModelTask该类并将其转换为内联,使其更加优雅:Callablesubmit()

modelFutures.add(executor.submit(() -> WekaModuler.loadModel(MODELS_LOCAL_DIR + SEP + modelFileName)));
Run Code Online (Sandbox Code Playgroud)

这通过了编译,运行,创建了执行器服务线程池,但是当需要调用实际的可调用对象时,它就卡住了。我尝试在里面放置一个断点WekaModuler::loadModel,但它永远不会在那里停止。我查看了线程转储,线程池中的所有线程都处于 RUNNABLE 状态,并指定以下堆栈跟踪:

"pool-2-thread-13" #27 prio=5 os_prio=0 tid=0x000000001da52000 nid=0xd78 in Object.wait() [0x0000000021fdf000]
   java.lang.Thread.State: RUNNABLE
        at com.evercompliant.weka.classifier.EverClassifier$$Lambda$4/1222094219.call(Unknown Source)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)

Callable内联类和实际实现类之间应该有什么区别吗Callable

我必须指出,我尝试用一​​些返回的虚拟任务来模拟同样的事情,Future<Integer>并且一切正常且符合预期。该发现指出实际域 ( WekaModuler) 存在问题。