我正在阅读有关Java中的期货和JavaScript中的Promises的文章。以下是我作为示例编写的代码。我的问题是分配给将来的任务何时开始执行?


当创建future时,如下所示:
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);
                }
            }
        });
    }
}

最佳答案

但是,为什么它迫使我将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);


当您下载某些内容时,可能要花一些时间(取决于大小,速度等),这就是为什么您最终会阻止futures .get()调用的原因-除非在此之前发生任何事情比下载要花费更长的时间,在这种情况下,.get()将立即返回(同样,仅当下载在.get()之前完成或遇到异常时)。

07-24 09:47
查看更多