Java set a callback from ExecutorService
If using Google Guava is an option, you could utilize the ListenableFuture interface in the following manner:
- Convert an
ExecutorService
to a ListeningExecutorService viaMoreExecutors.listeningDecorator(existingExecutorService)
- The
submit(Callable<V>)
method ofListeningExecutorService
has been narrowed to return aListenableFuture
, which is a subinterface ofFuture
. ListenableFuture
has anaddListener()
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 }});