diff --git a/core-java-modules/core-java-concurrency-advanced-3/pom.xml b/core-java-modules/core-java-concurrency-advanced-3/pom.xml
index df9834181f..8f275f4043 100644
--- a/core-java-modules/core-java-concurrency-advanced-3/pom.xml
+++ b/core-java-modules/core-java-concurrency-advanced-3/pom.xml
@@ -23,6 +23,37 @@
${assertj.version}
test
+
+
+ com.jcabi
+ jcabi-aspects
+ ${jcabi-aspects.version}
+
+
+
+ org.aspectj
+ aspectjrt
+ ${aspectjrt.version}
+ runtime
+
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+
+ org.cactoos
+ cactoos
+ ${cactoos.version}
+
+
+
+ com.ea.async
+ ea-async
+ ${ea-async.version}
+
@@ -36,6 +67,30 @@
${maven.compiler.target}
+
+ com.jcabi
+ jcabi-maven-plugin
+ ${jcabi-maven-plugin.version}
+
+
+
+ ajc
+
+
+
+
+
+ org.aspectj
+ aspectjtools
+ ${aspectjtools.version}
+
+
+ org.aspectj
+ aspectjweaver
+ ${aspectjweaver.version}
+
+
+
@@ -49,6 +104,14 @@
3.14.0
1.8
1.8
+ 0.22.6
+ 1.9.5
+ 28.2-jre
+ 0.43
+ 1.2.3
+ 0.14.1
+ 1.9.1
+ 1.9.1
diff --git a/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/async/EAAsyncExample.java b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/async/EAAsyncExample.java
new file mode 100644
index 0000000000..c7c893e731
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-advanced-3/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/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/async/JavaAsync.java b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/async/JavaAsync.java
new file mode 100644
index 0000000000..6f36f46154
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-advanced-3/src/main/java/com/baeldung/async/JavaAsync.java
@@ -0,0 +1,183 @@
+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.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;
+ }
+
+}