java.util.concurrent.Future.get()没有返回

Pau*_*ers 4 java concurrency multithreading future executorservice

我有以下Java代码:

final Future future = exeService.submit(
    new Runnable() {
        public void run() {
            myObject.doSomething();
        }
    }
);

future.get();
Run Code Online (Sandbox Code Playgroud)

在哪里exeService是一个实例

java.util.concurrent.ExecutorService
Run Code Online (Sandbox Code Playgroud)

问题是myObject.doSomething()永远不会返回,因此future.get()永远不会返回.

但是,如果我将调用替换submitexecute这样的调用:

exeService.execute(
    new Runnable() {
        public void run() {
            myObject.doSomething();
        }
    }
);
Run Code Online (Sandbox Code Playgroud)

呼叫myObject.doSomething()确实返回.我不知道这是否重要,但这doSomething()是一种void方法.

为什么doSomething()在使用execute时完成但在使用时没有submit

另外,我不需要使用Future.get(); 这似乎是最自然的方式.(我也遇到了同样的问题CountdownLatch.)重点是我需要等待才能doSomething()继续完成,并且由于复杂的原因我不会进入这里,我需要在一个单独的线程上启动它.如果有另一种方法可以做到这一点,那就没问题了.

paj*_*ton 15

与在Executor.execute()Javadoc中一样:

在将来的某个时间执行给定的命令.该命令可以在Executor实现的判断下在新线程,池化线程或调用线程中执行.

因此,该方法execute()立即返回,让您无法查询已提交任务的状态.

另一方面ExecutorService.submit():

提交Runnable任务以执行并返回表示该任务的Future.Future的get方法将在成功完成后返回null.

的Future.get()将返回唯一成功赛区之后,所以从来没有在您的案件.

这在Future.get()文档中进一步说明:

如果需要等待计算完成,然后检索其结果.

  • +1用于阅读问题并突破OP的混乱 (4认同)
  • 它在使用'执行'时"返回",因为事物只是在某个地方被解雇了,而他从不等待它完成.当使用submit()时,他确实等待它完成,但它永远不会完成.如果使用treadpoolExecutor,则有两个可能的原因:1.遗嘱执行人被束缚而不是其他东西.2. doSomething()永远不会返回.例如,这是一个无限循环. (3认同)
  • 是..当你使用`execute()`而不是`submit()`时,你怎么解释它"确实返回"? (2认同)

Bal*_*usC 7

我创建了一个SSCCE:

package com.stackoverflow.q2585971;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Test {

    public static void main(String args[]) throws Exception {
        ExecutorService executor = Executors.newCachedThreadPool();
        Future<?> future = executor.submit(
            new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        System.out.println("Epic fail.");
                    }
                }
            }
        );

        System.out.println("Waiting for task to finish..");
        future.get();
        System.out.println("Task finished!");
        executor.shutdown();
    }

}
Run Code Online (Sandbox Code Playgroud)

它工作得很好.它首先打印

Waiting for task to finish..

然后一秒钟后你就会看到

Task finished!

所以,你的问题出在其他地方.我会在这里复制我对你问题的评论:

你的问题很混乱.第一个结构应该可行.困惑在于"回归".你不只是意味着"完成"或"执行"吗?您的混淆似乎是基于future.get() 实际等待runnable完成的事实,因此将阻止线程并阻止它future.get()在行之后执行代码的残余.