java期货执行

时间:2014-08-01 14:27:57

标签: java java.util.concurrent

我正在阅读Java中的Futures和javascript中的Promises。下面是我编写的代码示例。我的问题是,分配给未来的任务的执行何时开始?

  1. 当创建未来如下线时:
    contentsFuture = startDownloading(new URL("http://www.example.com"));

  2. 或者当我们调用get方法时 final String contents = contentsFuture.get();

  3. 似乎执行在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);
                    }
                }
            });
        }
    }
    

3 个答案:

答案 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()之前完成下载或它遇到异常)。