From ad01d9d7be20f37787b3856c958c17b6b88bea95 Mon Sep 17 00:00:00 2001 From: Ivanov Date: Tue, 7 Apr 2026 20:46:33 +0300 Subject: [PATCH 1/2] task is done --- .../mate/academy/AsyncRequestProcessor.java | 21 ++++++++++++++++++- src/main/java/mate/academy/Main.java | 8 +++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/java/mate/academy/AsyncRequestProcessor.java b/src/main/java/mate/academy/AsyncRequestProcessor.java index ee5eea1..f7ac215 100644 --- a/src/main/java/mate/academy/AsyncRequestProcessor.java +++ b/src/main/java/mate/academy/AsyncRequestProcessor.java @@ -1,16 +1,35 @@ package mate.academy; +import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; public class AsyncRequestProcessor { private final Executor executor; + private final Map cache = new ConcurrentHashMap<>(); public AsyncRequestProcessor(Executor executor) { this.executor = executor; } public CompletableFuture processRequest(String userId) { - return null; + UserData cachedUserData = cache.get(userId); + if (cachedUserData != null) { + return CompletableFuture.completedFuture(cachedUserData); + } + + return CompletableFuture.supplyAsync(() -> { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Request processing was interrupted", e); + } + + UserData userData = new UserData(userId, "Details for " + userId); + cache.put(userId, userData); + return userData; + }, executor); } } diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index a3c9b9e..c3ad8b0 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -2,15 +2,14 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class Main { public static void main(String[] args) { - // Feel free to play with AsyncRequestProcessor in this main method if you want - ExecutorService executor = null; // Provide implementation that fits your needs + ExecutorService executor = Executors.newFixedThreadPool(4); AsyncRequestProcessor asyncRequestProcessor = new AsyncRequestProcessor(executor); - // Simulating multiple concurrent requests - String[] userIds = {"user1", "user2", "user3", "user1"}; // Note: "user1" is repeated + String[] userIds = {"user1", "user2", "user3", "user1"}; CompletableFuture[] futures = new CompletableFuture[userIds.length]; for (int i = 0; i < userIds.length; i++) { @@ -19,7 +18,6 @@ public static void main(String[] args) { .thenAccept(userData -> System.out.println("Processed: " + userData)); } - // Wait for all futures to complete CompletableFuture.allOf(futures).join(); executor.shutdown(); } From 6ac5c2dec16333b6ca282092809d137782504b77 Mon Sep 17 00:00:00 2001 From: Ivanov Date: Tue, 7 Apr 2026 20:51:00 +0300 Subject: [PATCH 2/2] fixed the issue according to comment --- .../mate/academy/AsyncRequestProcessor.java | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/main/java/mate/academy/AsyncRequestProcessor.java b/src/main/java/mate/academy/AsyncRequestProcessor.java index f7ac215..5b03fb8 100644 --- a/src/main/java/mate/academy/AsyncRequestProcessor.java +++ b/src/main/java/mate/academy/AsyncRequestProcessor.java @@ -7,29 +7,23 @@ public class AsyncRequestProcessor { private final Executor executor; - private final Map cache = new ConcurrentHashMap<>(); + private final Map> cache = new ConcurrentHashMap<>(); public AsyncRequestProcessor(Executor executor) { this.executor = executor; } public CompletableFuture processRequest(String userId) { - UserData cachedUserData = cache.get(userId); - if (cachedUserData != null) { - return CompletableFuture.completedFuture(cachedUserData); - } - - return CompletableFuture.supplyAsync(() -> { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException("Request processing was interrupted", e); - } - - UserData userData = new UserData(userId, "Details for " + userId); - cache.put(userId, userData); - return userData; - }, executor); + return cache.computeIfAbsent(userId, key -> + CompletableFuture.supplyAsync(() -> { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Request processing was interrupted", e); + } + return new UserData(key, "Details for " + key); + }, executor) + ); } }