How to asynchronously call a method in Java - java

I've been looking at Go's goroutines lately and thought it would be nice to have something similar in Java. As far as I've searched the common way to parallelize a method call is to do something like:
final String x = "somethingelse";
new Thread(new Runnable() {
public void run() {
x.matches("something");
}
}).start();
Thats not very elegant. Is there a better way of doing this? I needed such a solution in a project so I decided to implement my own wrapper class around a async method call.
I published my wrapper class in J-Go. But I don't know if it is a good solution. The usage is simple:
SampleClass obj = ...
FutureResult<Integer> res = ...
Go go = new Go(obj);
go.callLater(res, "intReturningMethod", 10); //10 is a Integer method parameter
//... Do something else
//...
System.out.println("Result: "+res.get()); //Blocks until intReturningMethod returns
or less verbose:
Go.with(obj).callLater("myRandomMethod");
//... Go away
if (Go.lastResult().isReady()) //Blocks until myRandomMethod has ended
System.out.println("Method is finished!");
Internally I'm using a class that implements Runnable and do some Reflection work to get the correct method object and invoking it.
I want some opinion about my tiny library and on the subject of making async method calls like this in Java. Is it safe? Is there already a simplier way?

I just discovered that there is a cleaner way to do your
new Thread(new Runnable() {
public void run() {
//Do whatever
}
}).start();
(At least in Java 8), you can use a lambda expression to shorten it to:
new Thread(() -> {
//Do whatever
}).start();
As simple as making a function in JS!

Java 8 introduced CompletableFuture available in package java.util.concurrent.CompletableFuture, can be used to make a asynch call :
CompletableFuture.runAsync(() -> {
// method call or code to be asynch.
});

You may wish to also consider the class java.util.concurrent.FutureTask.
If you are using Java 5 or later, FutureTask is a turnkey implementation of "A cancellable asynchronous computation."
There are even richer asynchronous execution scheduling behaviors available in the java.util.concurrent package (for example, ScheduledExecutorService), but FutureTask may have all the functionality you require.
I would even go so far as to say that it is no longer advisable to use the first code pattern you gave as an example ever since FutureTask became available. (Assuming you are on Java 5 or later.)

i don't like the idea of using Reflection for that.
Not only dangerous for missing it in some refactoring, but it can also be denied by SecurityManager.
FutureTask is a good option as the other options from the java.util.concurrent package.
My favorite for simple tasks:
Executors.newSingleThreadExecutor().submit(task);
little bit shorter than creating a Thread (task is a Callable or a Runnable)

You can use the Java8 syntax for CompletableFuture, this way you can perform additional async computations based on the result from calling an async function.
for example:
CompletableFuture.supplyAsync(this::findSomeData)
.thenApply(this:: intReturningMethod)
.thenAccept(this::notify);
More details can be found in this article

You can use #Async annotation from jcabi-aspects and AspectJ:
public class Foo {
#Async
public void save() {
// to be executed in the background
}
}
When you call save(), a new thread starts and executes its body. Your main thread continues without waiting for the result of save().

You can use Future-AsyncResult for this.
#Async
public Future<Page> findPage(String page) throws InterruptedException {
System.out.println("Looking up " + page);
Page results = restTemplate.getForObject("http://graph.facebook.com/" + page, Page.class);
Thread.sleep(1000L);
return new AsyncResult<Page>(results);
}
Reference: https://spring.io/guides/gs/async-method/

Java also provides a nice way of calling async methods. in java.util.concurrent we have ExecutorService that helps in doing the same. Initialize your object like this -
private ExecutorService asyncExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
and then call the function like-
asyncExecutor.execute(() -> {
TimeUnit.SECONDS.sleep(3L);}

You can use AsyncFunc from Cactoos:
boolean matches = new AsyncFunc(
x -> x.matches("something")
).apply("The text").get();
It will be executed at the background and the result will be available in get() as a Future.

It's probably not a real solution, but now - in Java 8 - You can make this code look at least a little better using lambda expression.
final String x = "somethingelse";
new Thread(() -> {
x.matches("something");
}
).start();
And You could even do this in one line, still having it pretty readable.
new Thread(() -> x.matches("something")).start();

This is not really related but if I was to asynchronously call a method e.g. matches(), I would use:
private final static ExecutorService service = Executors.newFixedThreadPool(10);
public static Future<Boolean> matches(final String x, final String y) {
return service.submit(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
return x.matches(y);
}
});
}
Then to call the asynchronous method I would use:
String x = "somethingelse";
try {
System.out.println("Matches: "+matches(x, "something").get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
I have tested this and it works. Just thought it may help others if they just came for the "asynchronous method".

There is also nice library for Async-Await created by EA: https://github.com/electronicarts/ea-async
From their Readme:
With EA Async
import static com.ea.async.Async.await;
import static java.util.concurrent.CompletableFuture.completedFuture;
public class Store
{
public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
{
if(!await(bank.decrement(cost))) {
return completedFuture(false);
}
await(inventory.giveItem(itemTypeId));
return completedFuture(true);
}
}
Without EA Async
import static java.util.concurrent.CompletableFuture.completedFuture;
public class Store
{
public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
{
return bank.decrement(cost)
.thenCompose(result -> {
if(!result) {
return completedFuture(false);
}
return inventory.giveItem(itemTypeId).thenApply(res -> true);
});
}
}

Related

How to test asynchronous method

I need to asynchronously fetch some data from DB, and then synchronously update currently cached data, with the one that was fetched.
At the moment my code looks like this:
#Asynchronous
public void fetchData() {
CompletableFuture.supplyAsync(() -> {
//Do some logic to fetch data
return fetchedData;
}).thenAccept(fetchedData -> updateCache(fetchedData));
}
My problem is that when I call this method in my tests, it instantly goes to thenAccept but fetchedData is empty. I've tried to change my method, and return CompletableFuture<List<Data>>, and call fetchData().join() in tests. It worked fine, but first - my app wouldn't build, since #Asynchronous need to return Future or void, and I don't think changing method just to test it is a good idea.
I've heard about Await library, but can not use it in current project.
I'am also not sure, if #Asynchronous is needed in my case? If I'm not mistaken, CompletableFuture should run in own thread by default?
Jacek, I think #Asynchronous annotation is not required. You can use the pure form of completable future. I provide below the sample code based upon the code you have provided.
public String getInfoFromDB() {
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Data from DB";
}
public void updateCache(String dataFromDB) {
System.out.println("Data from D : " + dataFromDB);
System.out.println("Doing some operations with data from DB");
}
public void fetchData() {
CompletableFuture cf =
CompletableFuture.supplyAsync(() -> getInfoFromDB())
.thenAccept(dataFromDB -> updateCache(dataFromDB));
cf.join();
}
You can use this useful library: awaitility

Vertx: executeBlocking() vs Future. What's the difference?

Vertx docs suggests to use executeBlocking() method when one needs to call blocking API. On the other hand Vertx also offers a notion of Future which basically do the same thing. But the executeBlocking() method isn't static. It is also not a simple wrapper around Future, and if you look at its implementation you'll see that it's pretty complex. What's the difference between these two?
Assume that I want to execute some long running task in an async way. Is there any difference between these two methods?
method 1:
doTheJob() {
Future<Void> future = Future.future();
executeLongRunningBlockingOperation();
future.complete();
return future;
}
doTheJob().setHandler(asyncResult -> {
// ... handle result
});
method 2:
vertx.executeBlocking(future -> {
executeLongRunningBlockingOperation();
future.complete();
}, res -> {
// ... handle result
});
Your first example is not a correct usage of Future. The call to executeLongRunningBlockingOperation() will block the main thread until that method has completed — i.e. nothing else can happen until the blocking operation finishes. In your second example the blocking call is spun off into a background thread and other things continue to happen while it executes.
To illustrate this with a more complete example, this code:
public void executeLongRunningBlockingOperation() {
Thread.sleep(5000);
}
public Future<Void> doTheJob() {
System.out.println("Doing the job...");
Future<Void> future = Future.future();
executeLongRunningBlockingOperation();
// this line will not be called until executeLongRunningBlockingOperation returns!
future.complete();
// nor will this method! This means that the method won't return until the long operation is done!
return future;
}
public static void main(String[] args) {
doTheJob().setHandler(asyncResult -> {
System.out.println("Finished the job");
});
System.out.println("Doing other stuff in the mean time...");
}
Will produce the following output:
Doing the job...
Finished the job
Doing other stuff in the mean time...
Whereas this code (using the executeBlocking):
...
public Future<Void> doTheJob() {
System.out.println("Doing the job...");
Future<Void> future = Future.future();
Vertx vertx = Vertx.vertx();
vertx.executeBlocking(call -> {
executeLongRunningBlockingOperation();
call.complete;
}, result -> {
// this will only be called once the blocking operation is done
future.complete();
});
// this method returns immediately since we are not blocking the main thread
return future;
}
...
Will produce:
Doing the job...
Doing other stuff in the mean time...
Finished the job
If you'd like to develop a better understanding of Vert.x I'd recommend the following hands-on tutorials:
https://vertx.io/docs/guide-for-java-devs/
http://escoffier.me/vertx-hol/

Calling multiple methods asynchronously and updating an object [duplicate]

I've been looking at Go's goroutines lately and thought it would be nice to have something similar in Java. As far as I've searched the common way to parallelize a method call is to do something like:
final String x = "somethingelse";
new Thread(new Runnable() {
public void run() {
x.matches("something");
}
}).start();
Thats not very elegant. Is there a better way of doing this? I needed such a solution in a project so I decided to implement my own wrapper class around a async method call.
I published my wrapper class in J-Go. But I don't know if it is a good solution. The usage is simple:
SampleClass obj = ...
FutureResult<Integer> res = ...
Go go = new Go(obj);
go.callLater(res, "intReturningMethod", 10); //10 is a Integer method parameter
//... Do something else
//...
System.out.println("Result: "+res.get()); //Blocks until intReturningMethod returns
or less verbose:
Go.with(obj).callLater("myRandomMethod");
//... Go away
if (Go.lastResult().isReady()) //Blocks until myRandomMethod has ended
System.out.println("Method is finished!");
Internally I'm using a class that implements Runnable and do some Reflection work to get the correct method object and invoking it.
I want some opinion about my tiny library and on the subject of making async method calls like this in Java. Is it safe? Is there already a simplier way?
I just discovered that there is a cleaner way to do your
new Thread(new Runnable() {
public void run() {
//Do whatever
}
}).start();
(At least in Java 8), you can use a lambda expression to shorten it to:
new Thread(() -> {
//Do whatever
}).start();
As simple as making a function in JS!
Java 8 introduced CompletableFuture available in package java.util.concurrent.CompletableFuture, can be used to make a asynch call :
CompletableFuture.runAsync(() -> {
// method call or code to be asynch.
});
You may wish to also consider the class java.util.concurrent.FutureTask.
If you are using Java 5 or later, FutureTask is a turnkey implementation of "A cancellable asynchronous computation."
There are even richer asynchronous execution scheduling behaviors available in the java.util.concurrent package (for example, ScheduledExecutorService), but FutureTask may have all the functionality you require.
I would even go so far as to say that it is no longer advisable to use the first code pattern you gave as an example ever since FutureTask became available. (Assuming you are on Java 5 or later.)
i don't like the idea of using Reflection for that.
Not only dangerous for missing it in some refactoring, but it can also be denied by SecurityManager.
FutureTask is a good option as the other options from the java.util.concurrent package.
My favorite for simple tasks:
Executors.newSingleThreadExecutor().submit(task);
little bit shorter than creating a Thread (task is a Callable or a Runnable)
You can use the Java8 syntax for CompletableFuture, this way you can perform additional async computations based on the result from calling an async function.
for example:
CompletableFuture.supplyAsync(this::findSomeData)
.thenApply(this:: intReturningMethod)
.thenAccept(this::notify);
More details can be found in this article
You can use #Async annotation from jcabi-aspects and AspectJ:
public class Foo {
#Async
public void save() {
// to be executed in the background
}
}
When you call save(), a new thread starts and executes its body. Your main thread continues without waiting for the result of save().
You can use Future-AsyncResult for this.
#Async
public Future<Page> findPage(String page) throws InterruptedException {
System.out.println("Looking up " + page);
Page results = restTemplate.getForObject("http://graph.facebook.com/" + page, Page.class);
Thread.sleep(1000L);
return new AsyncResult<Page>(results);
}
Reference: https://spring.io/guides/gs/async-method/
Java also provides a nice way of calling async methods. in java.util.concurrent we have ExecutorService that helps in doing the same. Initialize your object like this -
private ExecutorService asyncExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
and then call the function like-
asyncExecutor.execute(() -> {
TimeUnit.SECONDS.sleep(3L);}
You can use AsyncFunc from Cactoos:
boolean matches = new AsyncFunc(
x -> x.matches("something")
).apply("The text").get();
It will be executed at the background and the result will be available in get() as a Future.
It's probably not a real solution, but now - in Java 8 - You can make this code look at least a little better using lambda expression.
final String x = "somethingelse";
new Thread(() -> {
x.matches("something");
}
).start();
And You could even do this in one line, still having it pretty readable.
new Thread(() -> x.matches("something")).start();
This is not really related but if I was to asynchronously call a method e.g. matches(), I would use:
private final static ExecutorService service = Executors.newFixedThreadPool(10);
public static Future<Boolean> matches(final String x, final String y) {
return service.submit(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
return x.matches(y);
}
});
}
Then to call the asynchronous method I would use:
String x = "somethingelse";
try {
System.out.println("Matches: "+matches(x, "something").get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
I have tested this and it works. Just thought it may help others if they just came for the "asynchronous method".
There is also nice library for Async-Await created by EA: https://github.com/electronicarts/ea-async
From their Readme:
With EA Async
import static com.ea.async.Async.await;
import static java.util.concurrent.CompletableFuture.completedFuture;
public class Store
{
public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
{
if(!await(bank.decrement(cost))) {
return completedFuture(false);
}
await(inventory.giveItem(itemTypeId));
return completedFuture(true);
}
}
Without EA Async
import static java.util.concurrent.CompletableFuture.completedFuture;
public class Store
{
public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
{
return bank.decrement(cost)
.thenCompose(result -> {
if(!result) {
return completedFuture(false);
}
return inventory.giveItem(itemTypeId).thenApply(res -> true);
});
}
}

How to make some asynch calls in a loop

In a loop i need to make some checks, performed actually in some another verticle. In each iteration of my loop i need to check the response code, returned from those verticle and make some decision accordingly. In some other words i need to stop the execution of my loop and somehow wait till asynch. call returns. But such execution stop violates the vert.x philosophy, which states that main thread execution should be never stopped. How can i do it in the scope of Vert.x? So far i don't know how to do this. Any suggestions/code samples/urls to smth. like a solution would b highly appreciated.
Thanks!
When working with Vert.x you need to think less in terms of loops, and more in terms of callbacks.
You should use eventBus to communicate between vertices.
Let's say that what you want is something similar to this pseudocode:
for (int i = 0; i < 4; i++) {
int result = getVerticleResult();
System.out.println(result);
}
So, just a very basic example
class LooperVerticle extends AbstractVerticle {
private int i = 4;
#Override
public void start() throws Exception {
doWork();
}
private void doWork() {
vertx.eventBus().send("channel", "", (o) -> {
if (o.succeeded()) {
System.out.println(o.result().body());
i--;
if (i > 0) {
doWork();
}
}
});
}
}
class WorkerVerticle extends AbstractVerticle {
#Override
public void start() throws Exception {
vertx.eventBus().consumer("channel", (o) -> {
// Generate some random number
int num = ThreadLocalRandom.current().nextInt(0, 9);
// Simulate slowness
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
o.reply(num);
});
}
}
To test:
public class EventBusExample {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(new LooperVerticle());
vertx.deployVerticle(new WorkerVerticle());
}
}
I think you need to use FutureTask and store them in a Collection and use FutureTask.get() to retrieve the result when needed which is a blocking call.
It sounds like a use case for reactive steam processing.
In general such problem could be solved using 2 parties:
a producer that executes tasks and returns asynchronous results
a handler that subscribes to results and performs another tasks
There is a way to configure producer to perform tasks only when there is a subscriber. And on other side subscriber can decide to unsubscribe from producer on some condition.
I'm not familiar with vertx capabilities for reactive streams. But I would start from RxJava integration
http://vertx.io/docs/vertx-rx/java/

Best way to sequentially pass list values to single value consumer?

I'm toying with Java8's streams and CompletableFutures. My pre-existing code has a class that takes a single URL and downloads it:
public class FileDownloader implements Runnable {
private URL target;
public FileDownloader(String target) {
this.target = new URL(target);
}
public void run() { /* do it */ }
}
Now, this class gets it's information from another part that emits List<String> (a number of targets on a single host).
I've switched the surrounding code to CompletableFuture:
public class Downloader {
public static void main(String[] args) {
List<String> hosts = fetchTargetHosts();
for (String host : hosts) {
HostDownloader worker = new HostDownloader(host);
CompletableFuture<List<String>> future =
CompletableFuture.supplyAsync(worker);
future.thenAcceptAsync((files) -> {
for (String target : files) {
new FileDownloader(target).run();
}
});
}
}
public static class HostDownloader implements Supplier<List<String>> {
/* not shown */
}
/* My implementation should either be Runnable or Consumer.
Please suggest based on a idiomatic approach to the main loop.
*/
public static class FileDownloader implements Runnable, Consumer<String> {
private String target;
public FileDownloader(String target) {
this.target = target;
}
#Override
public void run() { accept(this.target); }
#Override
public void accept(String target) {
try (Writer output = new FileWriter("/tmp/blubb")) {
output.write(new URL(target).getContent().toString());
} catch (IOException e) { /* just for demo */ }
}
}
}
Now, this doesn't feel natural. I'm producing a stream of Strings and my FileDownloader consumes one of them at a time. Is there a readymade to enable my single value Consumer to work with Lists or am I stuck with the for loop here?
I know it's trivial to move the loop into the accept and just make a Consumer<List<String>>, that's not the point.
There is no point in dissolving two directly dependent steps into two asynchronous steps. They are still dependent and if the separation has any effect, it won’t be a positive one.
You can simply use
List<String> hosts = fetchTargetHosts();
FileDownloader fileDownloader = new FileDownloader();
for(String host: hosts)
CompletableFuture.runAsync(()->
new HostDownloader(host).get().forEach(fileDownloader));
or, assuming that FileDownloader does not have mutable state regarding a download:
for(String host: hosts)
CompletableFuture.runAsync(()->
new HostDownloader(host).get().parallelStream().forEach(fileDownloader));
This still has the same level of concurrency as your original approach using supplyAsync plus thenAcceptAsync, simply because these two dependent steps can’t run concurrently anyway, so the simple solution is to put both steps into one concise operation that will be executed asynchronously.
However, at this point it’s worth noting that the entire use of CompletableFuture is not recommended for this operation. As it’s documentation states:
All async methods without an explicit Executor argument are performed using the ForkJoinPool.commonPool()
The problem with the common pool is that its pre-configured concurrency level depends on the number of CPU cores and won’t be adjusted if threads are blocked during an I/O operation. In other words, it is unsuitable for I/O operations.
Unlike Stream, CompletableFuture allows you to specify an Executor for the async operations, so you can configure your own Executor to be suitable for I/O operations, on the other hand, when you deal with an Executor anyway, there is no need for CompletableFuture at all, at least not for such a simple task:
List<String> hosts = fetchTargetHosts();
int concurrentHosts = 10;
int concurrentConnections = 100;
ExecutorService hostEs=Executors.newWorkStealingPool(concurrentHosts);
ExecutorService connEs=Executors.newWorkStealingPool(concurrentConnections);
FileDownloader fileDownloader = new FileDownloader();
for(String host: hosts) hostEs.execute(()-> {
for(String target: new HostDownloader(host).get())
connEs.execute(()->fileDownloader.accept(target));
});
At this place you may consider either, to inline the code of FileDownloader.accept into the lambda expression or to revert it to be a Runnable so that you can change the inner loop’s statement to connEs.execute(new FileDownloader(target)).
An alternative would be:
CompletableFuture.supplyAsync(worker)
.thenApply(list -> list.stream().map(FileDownloader::new))
.thenAccept(s -> s.forEach(FileDownloader::run));
I think you need to do forEach like that:
for (String host : hosts) {
HostDownloader worker = new HostDownloader(host);
CompletableFuture<List<String>> future =
CompletableFuture.supplyAsync(worker);
future.thenAcceptAsync(files ->
files.stream()
.forEach(target -> new FileDownloader(target).run())
);
}
by the way, you could do the same with the main loop...
edit:
Since OP edited original post, adding implementation details of FileDownloader, I am editing my answer accordingly. Java 8 functional interface is meant to allow the use of lambda expr in place of concrete Class. It is not meant to be implemented like regular interface 9although it can be) Therefor, "to take advantage of" Java 8 consumer means replacing FileDownloader with the code of accept like this:
for (String host : hosts) {
HostDownloader worker = new HostDownloader(host);
CompletableFuture<List<String>> future = CompletableFuture.supplyAsync(worker);
future.thenAcceptAsync(files ->
files.forEach(target -> {
try (Writer output = new FileWriter("/tmp/blubb")) {
output.write(new URL(target).getContent().toString());
} catch (IOException e) { /* just for demo */ }
})
);
}

Categories

Resources