Java set a callback from ExecutorService Java set a callback from ExecutorService multithreading multithreading

Java set a callback from ExecutorService


If using Google Guava is an option, you could utilize the ListenableFuture interface in the following manner:

  1. Convert an ExecutorService to a ListeningExecutorService via MoreExecutors.listeningDecorator(existingExecutorService)
  2. The submit(Callable<V>) method of ListeningExecutorService has been narrowed to return a ListenableFuture, which is a subinterface of Future.
  3. ListenableFuture has an addListener() method so you can register a callback to be run when the future is completed.


ExecutorService#submit return FutureTask<T> which helps you to retrieve result and the ExecutorService#get method will block execution until the computation is not completed. Example -

ExecutorService executor = Executors.newFixedThreadPool(10);Future<Long> future = executor.submit(new Callable<Long>(){       @Override       public Long call() throws Exception {           long sum = 0;           for (long i = 0; i <= 10000000l; i++) {               sum += i;           }           return sum;       }});Long result = future.get();System.out.println(result);


You can add a callback for when a thread returns in Java 8+ using CompletableFuture as in the following, where t is the result of your long-running computation,

CompletableFuture.supplyAsync(() -> {    T t = new T();    // do something    return t;}).thenApply(t -> {    // process t});

If you want to use callbacks in just Java 7, you could do something like,

int x = 10;ExecutorService fixedThreadPool = Executors.newFixedThreadPool(x);Future<T> result = fixedThreadPool.submit(() -> {    // do calculation    return T;});fixedThreadPool.submit(() -> {    long minutesToWait = 5;    T t = null;    try {        t = result.get(minutesToWait, TimeUnit.MINUTES);    } catch (InterruptedException | ExecutionException | TimeoutException e) {        LOGGER.error(e);    }    if (t != null) {        // process t    }});