我正在阅读Java中的Futures和javascript中的Promises。下面是我编写的代码示例。我的问题是,分配给未来的任务的执行何时开始?
当创建未来如下线时:
contentsFuture = startDownloading(new URL("http://www.example.com"));
或者当我们调用get
方法时
final String contents = contentsFuture.get();
似乎执行在get
调用期间开始,因为它是一个阻塞调用,但是为什么它强迫我将startDownloading
调用放在try catch块中?
public class Futures1 {
private static final ExecutorService pool = Executors
.newFixedThreadPool(10);
public static void main(String[] args) {
Future<String> contentsFuture = null;
try {
contentsFuture = startDownloading(new URL("http://www.example.com"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
// other computation
try {
final String contents = contentsFuture.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
public static Future<String> startDownloading(final URL url) {
return pool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
try (InputStream input = url.openStream()) {
return IOUtils.toString(input, StandardCharsets.UTF_8);
}
}
});
}
}
答案 0 :(得分:2)
ExecutorService选择何时在提交基础任务后启动它。因此,通常会在某个时间在之间调用<{1}}和调用ExecutorService.submit
。
答案 1 :(得分:2)
致电startDownloading
后开始执行。
get()
等待结果(因此可能是阻塞调用)。如果您不希望阻止,请在执行其他操作时致电isDone()
。
答案 2 :(得分:1)
但是为什么它迫使我把startDownloading调用放在try catch块中?
在startDownloading中捕获的异常是由于构造了URL对象。如果您没有调用startDownloading并且刚刚创建了一个URL对象,那么它将是相同的,即;
URL url = null;
try {
url = new URL("http://www.example.com");
} catch (MalformedURLException e) {
//Catch badly formed URL.
e.printStackTrace();
}
if (url != null)
contentsFuture = startDownloading(url);
当您下载某些内容时,可能需要一段时间(取决于大小,速度等),这将是您最终阻止期货.get()调用的原因 - 除非在此之前发生任何事情需要更长时间比下载,在这种情况下.get()将立即返回(再次只有在.get()之前完成下载或它遇到异常)。