From fcb6efbf0089b19f3a11d0559e6065e1cecbd2f1 Mon Sep 17 00:00:00 2001 From: Wynn Teo <49014791+wynnteo@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:36:34 +0800 Subject: [PATCH] BAEL-6622 (#15905) * BAEL-7490 read write file in separate thread * Change the to try resources * Update the code to sync with article * BAEL-6622 compare thenApply() and thenApplyAsync() * BAEL-6622 change to unit test * Tidy up the code --- .../ThenApplyAndThenApplyAsyncUnitTest.java | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/applyvsapplyasync/ThenApplyAndThenApplyAsyncUnitTest.java diff --git a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/applyvsapplyasync/ThenApplyAndThenApplyAsyncUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/applyvsapplyasync/ThenApplyAndThenApplyAsyncUnitTest.java new file mode 100644 index 0000000000..ee7f6d7a82 --- /dev/null +++ b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/applyvsapplyasync/ThenApplyAndThenApplyAsyncUnitTest.java @@ -0,0 +1,91 @@ +package com.baeldung.concurrent.applyvsapplyasync; + +import org.junit.jupiter.api.Test; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class ThenApplyAndThenApplyAsyncUnitTest { + + @Test + public void givenCompletableFuture_whenUsingThenApply_thenResultIsAsExpected() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> 5); + CompletableFuture thenApplyResultFuture = future.thenApply(num -> "Result: " + num); + + String thenApplyResult = thenApplyResultFuture.join(); + assertEquals("Result: 5", thenApplyResult); + } + + @Test + public void givenCompletableFuture_whenUsingThenApplyAsync_thenResultIsAsExpected() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> 5); + CompletableFuture thenApplyAsyncResultFuture = future.thenApplyAsync(num -> "Result: " + num); + + String thenApplyAsyncResult = thenApplyAsyncResultFuture.join(); + assertEquals("Result: 5", thenApplyAsyncResult); + } + + @Test + public void givenCompletableFuture_whenUsingThenApply_thenExceptionIsPropagated() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> 5); + CompletableFuture resultFuture = future.thenApply(num -> "Result: " + num / 0); + assertThrows(CompletionException.class, () -> resultFuture.join()); + } + + @Test + public void givenCompletableFuture_whenUsingThenApply_thenExceptionIsHandledAsExpected() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> 5); + CompletableFuture resultFuture = future.thenApply(num -> "Result: " + num / 0); + try { + // Accessing the result + String result = resultFuture.join(); + assertEquals("Result: 5", result); + } catch (CompletionException e) { + assertEquals("java.lang.ArithmeticException: / by zero", e.getMessage()); + System.err.println("Exception caught: " + e.getMessage()); + } + } + + @Test + public void givenCompletableFuture_whenUsingThenApplyAsync_thenExceptionIsHandledAsExpected() { + CompletableFuture future = CompletableFuture.supplyAsync(() -> 5); + CompletableFuture thenApplyAsyncResultFuture = future.thenApplyAsync(num -> "Result: " + num / 0); + + String result = thenApplyAsyncResultFuture.handle((res, error) -> { + if (error != null) { + // Handle the error appropriately, e.g., return a default value + return "Error occurred"; + } else { + return res; + } + }) + .join(); // Now join() won't throw the exception + assertEquals("Error occurred", result); + } + + @Test + public void givenCompletableFutureWithExecutor_whenUsingThenApplyAsync_thenThreadExecutesAsExpected() { + ExecutorService customExecutor = Executors.newFixedThreadPool(4); + + CompletableFuture future = CompletableFuture.supplyAsync(() -> { + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return 5; + }, customExecutor); + + CompletableFuture resultFuture = future.thenApplyAsync(num -> "Result: " + num, customExecutor); + + String result = resultFuture.join(); + assertEquals("Result: 5", result); + + customExecutor.shutdown(); + } +}