Asynchronous Java Programming Using Blocking APIs
I am working on a Java project that uses certain API locks.
I would like to use asynchronous programming and callbacks, so I don't need to block while waiting for the result. I've looked into using Java Future
, but the only way I think I could use it is by calling a method get()
that blocks. I am open to using other asynchronous programming techniques.
My current code looks like this.
Object res = blockingAPI();
sendToClient(res);
If I used Future
, I would do it like this. But my understanding is get()
blocking.
private final int THREADS = Runtime.getRuntime().availableProcessors();
private ExecutorService executor = Executors.newFixedThreadPool(THREADS);
public void invokeApi() {
Future<Object> future = executor.submit(new Callable<Object>() {
public Object call() {
return result;
}
});
Object result = future.get(5, TimeUnit.SECONDS)
}
How can I implement this so that the function get()
is mostly handled by a callback that is automatically called when the result is available?
source to share
Several parameters.
One is to turn your future into a CompletableFuture:
public static <T> CompletableFuture<T> makeCompletableFuture(Future<T> future) {
return CompletableFuture.supplyAsync(() -> {
try {
return future.get();
} catch (InterruptedException|ExecutionException e) {
throw new RuntimeException(e);
}
});
}
Another is to use Guava ListenableFuture
:
ListeningExecutorService service = MoreExecutors.listeningDecorator(executor);
ListenableFuture<T> future = service.submit(callable);
Futures.addCallback(future, new FutureCallback<T>() {
public void onSuccess(T t) {
// ...
}
public void onFailure(Throwable thrown) {
// ...
}
});
You can also use Akka Futures , which are very complex.
source to share
You have two main options:
-
periodically pool for the result:
Future
The API offers a methodisDone()
to check if the result of a Callable computation is ready. It is a non-blocking method that returns a boolean value, true if the result is ready, otherwise false. -
Subscribe to the result and attach useful work, waiting for the notification that the result is ready. There are many ways to accomplish this, and perhaps the simplest would be to use
Observer Pattern
.
Some other useful patterns that can be used in asynchronous programming, although not very well known, are Active object
and Half sync - half async
.
The active object works in such a way that clients call concurrent object services with blocking. There is a scheduling engine that processes these results by priority, as they come in, or other criteria.
The example below has an implementation where the client services are wrapped in a Runnable, but you can easily modify it to port the services to the Callable instead and set a proxy between the client and the Active object to subscribe to the result from the callee.
source to share