我有以下Java代码:
final Future future = exeService.submit(
new Runnable() {
public void run() {
myObject.doSomething();
}
}
);
future.get();
其中
exeService
是 的实例
java.util.concurrent.ExecutorService
问题是
myObject.doSomething()
永远不会返回,因此,future.get()
永远不会返回。
但是,如果我将对
submit
的调用替换为对 execute
的调用,如下所示:
exeService.execute(
new Runnable() {
public void run() {
myObject.doSomething();
}
}
);
对
myObject.doSomething()
的调用确实返回。 我不知道这是否重要,但是 doSomething()
是一个 void
方法。
为什么使用
doSomething()
时execute
完成而使用submit
时不完成?
另外,我不需要使用
Future.get()
;这似乎是最自然的做法。 (我也遇到了与 CountdownLatch
相同的问题。)重点是我需要等待 doSomething()
完成才能继续,而且,由于复杂的原因,我不会在这里讨论,我需要启动它一个单独的线程。 如果有另一种可行的方法,那就太好了。
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();
}
}
它工作得很好。它首先打印
等待任务完成..
然后一秒钟后你就看到了
任务完成!
所以,你的问题出在其他地方。我将在这里重复我对你的问题的评论:
你的问题很令人困惑。第一个构造应该可以工作。困惑就在于“回归”。你不是指“完成”或“执行”吗?您的困惑似乎是基于以下事实:
future.get()
实际上等待可运行程序完成,因此会阻塞线程并阻止它执行future.get()
行之后的剩余代码。
get(). This method blocks the current thread until a future instance completes its work, thus requiring the use of one thread more than the work that must be performed just to manage what happens when it is done
Integer res = executorService.submit(
myObject::doSomething
).get();
System.out.println(res);
executorService.shutdown();
执行 future.get 和上面的区别在于,在前一种方法中,您创建一个 future 对象并继续,然后尝试获取尚未准备好的结果。在这里,直到结果准备好并存储在 Integer 变量中之前,您不会继续前进。