Search code examples
javajava.util.concurrent

java Futures execution


I was reading about Futures in Java and Promises in javascript. Below is the code I wrote as an example. My question is when does the execution of task assigned to future start?

  1. When the future is created as in below line:
    contentsFuture = startDownloading(new URL("http://www.example.com"));

  2. Or when we call the get method
    final String contents = contentsFuture.get();

It seems that execution starts during get call as it is a blocking call, but then why it is forcing me to put the startDownloading call in the try catch block?

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);
                }
            }
        });
    }
}

Solution

  • but then why it is forcing me to put the startDownloading call in the try catch block?

    The exception being caught around startDownloading is due to the construction of the URL object. If you didn't call startDownloading and just created a URL object, it would be the same, ie;

        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);
    

    As you are downloading something, that could take a while (depending on size, speed, etc), which will be why you'll end up blocking on the futures .get() call - unless whatever occurs before that takes longer than the download, in which case .get() would return immediately (again only if the download completed before .get() or it encountered an exception).