Submitting Tasks to ExecutorService

Waiting for Results

How can developer know when a task submitted to an ExecutorService is complete ? As it was mentioned above, the submit() method returns a Future<V> object, that can be used to determine the result, for instance

Future<?> future = service.submit(() -> System.out.println("Hello"));

The Future class includes methods that are useful in determining the state of a task, see table

Method Name Description
boolean isDone() Returns true if the task was completed, threw an exception, or was cancelled
boolean isCancelled() Returns true if the task was cancelled before it completed normally
boolean cancel() Attempts to cancel execution of the task
V get() Retrieves the result of a task, waiting endlessly if it is not yet available
V get(long timeout, TimeUnit unit) Retrieves the result of a task, waiting the specified amount of time. If the result is not ready by the time the timeout is reached, a checked TimeoutException will be thrown

The following example shows the use of Future instance :

public class FutureExample {
    private static int counter;

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService service = null;
        try {
            service = Executors.newSingleThreadExecutor();
            Future<?> result = service.submit(() -> {
                for (int i = 0; i < 500; i++) {
                    FutureExample.counter++;
                    try {
                        Thread.sleep(19);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            result.get(10, TimeUnit.SECONDS);
            System.out.println("Reached!");
        } catch (TimeoutException e) {
            System.out.println("Not reached in time");
        } finally {
            if (service != null) {
                service.shutdown();
            }
        }
    }
}

This example uses Thread class, but not directly – but by turning to ExecutorService. This is the essence of Concurrency API: to do complex things with threads without using the Thread class directly. The code in example above also waits at most 10 seconds, following a TimeoutException if the task is not done.

TimeUnit is an enum type, and its values define the order of duration (TimeUnit.NANOSECONDS, TimeUnit.MICROSECONDS, … , TimeUnit.DAYS). It is widely used in Concurrency API. TimeUnit is helpful for using instead of Thread.sleep(int milliseconds) : TimeUnit.SECONDS.sleep(duration);It is more clearly and easier to perceive.

Previous

Leave a Reply

Your email address will not be published. Required fields are marked *