From 9cd73de5cc9b770887f09b6cde4672762d666c57 Mon Sep 17 00:00:00 2001 From: Anshul BANSAL Date: Wed, 1 Jan 2020 16:00:57 +0200 Subject: [PATCH] BAEL-3596 - Asynchronous Method Calls in Java --- java-async/pom.xml | 109 +++++++--- .../main/java/com/baeldung/async/Async.java | 46 ----- .../com/baeldung/async/EAAsyncExample.java | 57 ++++++ .../java/com/baeldung/async/JavaAsync.java | 186 ++++++++++++++++++ .../com/baeldung/async/AsyncUnitTest.java | 9 - 5 files changed, 323 insertions(+), 84 deletions(-) delete mode 100644 java-async/src/main/java/com/baeldung/async/Async.java create mode 100644 java-async/src/main/java/com/baeldung/async/EAAsyncExample.java create mode 100644 java-async/src/main/java/com/baeldung/async/JavaAsync.java delete mode 100644 java-async/src/main/resources/com/baeldung/async/AsyncUnitTest.java diff --git a/java-async/pom.xml b/java-async/pom.xml index 56ff53321f..17cdabbb06 100644 --- a/java-async/pom.xml +++ b/java-async/pom.xml @@ -1,37 +1,88 @@ - 4.0.0 - java-async - 0.1.0-SNAPSHOT - java-async - jar + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + java-async + java-async + jar + 1.0 - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../parent-java - + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + - - - + + + com.jcabi + jcabi-aspects + 0.22.6 + - - java-async - - - src/main/resources - true - - - + + org.aspectj + aspectjrt + 1.9.5 + runtime + - - 1.0.3 - 3.6.1 - + + com.google.guava + guava + 28.1-jre + + + + org.cactoos + cactoos + 0.43 + + + + com.ea.async + ea-async + 1.2.3 + + + + + java-async + + + src/main/resources + true + + + + + + com.jcabi + jcabi-maven-plugin + 0.14.1 + + + + ajc + + + + + + org.aspectj + aspectjtools + 1.9.1 + + + org.aspectj + aspectjweaver + 1.9.1 + + + + + diff --git a/java-async/src/main/java/com/baeldung/async/Async.java b/java-async/src/main/java/com/baeldung/async/Async.java deleted file mode 100644 index b505077d10..0000000000 --- a/java-async/src/main/java/com/baeldung/async/Async.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.baeldung.async; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -public class Async { - - public static void main(String[] args) { - System.out.println("hello world!!"); - - try { - Future completableFuture = calculateAsync(); - - String result = completableFuture.get(); - - System.out.println(result); - - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ExecutionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - - CompletableFuture.runAsync(() -> { - System.out.println("This is Async"); - }); - } - - public static Future calculateAsync() throws InterruptedException { - CompletableFuture completableFuture = new CompletableFuture<>(); - - Executors.newCachedThreadPool().submit(() -> { - Thread.sleep(500); - completableFuture.complete("Hello"); - return null; - }); - - return completableFuture; - } - -} \ No newline at end of file diff --git a/java-async/src/main/java/com/baeldung/async/EAAsyncExample.java b/java-async/src/main/java/com/baeldung/async/EAAsyncExample.java new file mode 100644 index 0000000000..c7c893e731 --- /dev/null +++ b/java-async/src/main/java/com/baeldung/async/EAAsyncExample.java @@ -0,0 +1,57 @@ +package com.baeldung.async; + +import static com.ea.async.Async.await; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import com.ea.async.Async; + +public class EAAsyncExample { + + static { + Async.init(); + } + + public static void main(String[] args) throws Exception { + usingCompletableFuture(); + usingAsyncAwait(); + } + + public static void usingCompletableFuture() throws InterruptedException, ExecutionException, Exception { + CompletableFuture completableFuture = hello() + .thenComposeAsync(hello -> mergeWorld(hello)) + .thenAcceptAsync(helloWorld -> print(helloWorld)) + .exceptionally( throwable -> { + System.out.println(throwable.getCause()); + return null; + }); + completableFuture.get(); + } + + public static CompletableFuture hello() { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello"); + return completableFuture; + } + + public static CompletableFuture mergeWorld(String s) { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> { + return s + " World!"; + }); + return completableFuture; + } + + public static void print(String str) { + CompletableFuture.runAsync(() -> System.out.println(str)); + } + + private static void usingAsyncAwait() { + try { + String hello = await(hello()); + String helloWorld = await(mergeWorld(hello)); + await(CompletableFuture.runAsync(() -> print(helloWorld))); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/java-async/src/main/java/com/baeldung/async/JavaAsync.java b/java-async/src/main/java/com/baeldung/async/JavaAsync.java new file mode 100644 index 0000000000..c1c2c98550 --- /dev/null +++ b/java-async/src/main/java/com/baeldung/async/JavaAsync.java @@ -0,0 +1,186 @@ +package com.baeldung.async; + +import static com.ea.async.Async.await; + +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import com.google.common.util.concurrent.AsyncCallable; +import com.google.common.util.concurrent.Callables; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.jcabi.aspects.Async; +import com.jcabi.aspects.Loggable; + +public class JavaAsync { + + static { + com.ea.async.Async.init(); + } + + private static final ExecutorService threadpool = Executors.newCachedThreadPool(); + + public static void main (String[] args) throws InterruptedException, ExecutionException { + int number = 20; + + //Thread Example + factorialUsingThread(number).start(); + + //FutureTask Example + Future futureTask = factorialUsingFutureTask(number); + System.out.println("Factorial of " + number + " is: " + futureTask.get()); + + // CompletableFuture Example + Future completableFuture = factorialUsingCompletableFuture(number); + System.out.println("Factorial of " + number + " is: " + completableFuture.get()); + + // EA Async example + System.out.println("Factorial of " + number + " is: " + factorialUsingEAAsync(number)); + + // cactoos async example + Future asyncFuture = factorialUsingCactoos(number); + System.out.println("Factorial of " + number + " is: " + asyncFuture.get()); + + // Guava example + ListenableFuture guavaFuture = factorialUsingGuavaServiceSubmit(number); + System.out.println("Factorial of " + number + " is: " + guavaFuture.get()); + + ListenableFuture guavaFutures = factorialUsingGuavaFutures(number); + System.out.println("Factorial of " + number + " is: " + guavaFutures.get()); + + // @async jcabi-aspect example + Future aspectFuture = factorialUsingJcabiAspect(number); + System.out.println("Factorial of " + number + " is: " + aspectFuture.get()); + + } + + /** + * Finds factorial of a number + * @param number + * @return + */ + public static long factorial(int number) { + long result = 1; + for(int i=number;i>0;i--) { + result *= i; + } + return result; + } + + /** + * Finds factorial of a number using Thread + * @param number + * @return + */ + @Loggable + public static Thread factorialUsingThread(int number) { + Thread newThread = new Thread(() -> { + System.out.println("Factorial of " + number + " is: " + factorial(number)); + }); + + return newThread; + } + + /** + * Finds factorial of a number using FutureTask + * @param number + * @return + */ + @Loggable + public static Future factorialUsingFutureTask(int number) { + Future futureTask = threadpool.submit(() -> factorial(number)); + + while (!futureTask.isDone()) { + System.out.println("FutureTask is not finished yet..."); + } + + return futureTask; + } + + /** + * Finds factorial of a number using CompletableFuture + * @param number + * @return + */ + @Loggable + public static Future factorialUsingCompletableFuture(int number) { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> factorial(number)); + return completableFuture; + } + + /** + * Finds factorial of a number using EA Async + * @param number + * @return + */ + @Loggable + public static long factorialUsingEAAsync(int number) { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> factorial(number)); + long result = await(completableFuture); + return result; + } + + /** + * + * Finds factorial of a number using Async of Cactoos + * @param number + * @return + * @throws InterruptedException + * @throws ExecutionException + */ + @Loggable + public static Future factorialUsingCactoos(int number) throws InterruptedException, ExecutionException { + org.cactoos.func.Async asyncFunction = new org.cactoos.func.Async(input -> factorial(input)); + Future asyncFuture = asyncFunction.apply(number); + return asyncFuture; + } + + /** + * Finds factorial of a number using Guava's ListeningExecutorService.submit() + * @param number + * @return + */ + @Loggable + public static ListenableFuture factorialUsingGuavaServiceSubmit(int number) { + ListeningExecutorService service = MoreExecutors.listeningDecorator(threadpool); + ListenableFuture factorialFuture = (ListenableFuture) service.submit(()-> factorial(number)); + return factorialFuture; + } + + /** + * Finds factorial of a number using Guava's Futures.submitAsync() + * @param number + * @return + */ + @Loggable + public static ListenableFuture factorialUsingGuavaFutures(int number) { + ListeningExecutorService service = MoreExecutors.listeningDecorator(threadpool); + AsyncCallable asyncCallable = Callables.asAsyncCallable(new Callable() { + public Long call() { + return factorial(number); + } + }, service); + return Futures.submitAsync(asyncCallable, service); + } + + /** + * + * Finds factorial of a number using @Async of jcabi-aspects + * @param number + * @return + */ + @Async + @Loggable + public static Future factorialUsingJcabiAspect(int number) { + Future factorialFuture = CompletableFuture.supplyAsync(() -> factorial(number)); + return factorialFuture; + } + +} diff --git a/java-async/src/main/resources/com/baeldung/async/AsyncUnitTest.java b/java-async/src/main/resources/com/baeldung/async/AsyncUnitTest.java deleted file mode 100644 index 57a61dbfe2..0000000000 --- a/java-async/src/main/resources/com/baeldung/async/AsyncUnitTest.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.baeldung.async; - -public class AsyncUnitTest { - - public static void main(String[] args) { - System.out.println("hello"); - } - -} \ No newline at end of file