From caeed2953ccd0d2709b00561762f6a61b04a94f6 Mon Sep 17 00:00:00 2001 From: Jacek Kubiak Date: Tue, 10 Feb 2026 08:30:04 +0100 Subject: [PATCH 1/3] Task to check --- .../mate/academy/AsyncRequestProcessor.java | 27 ++++++++++++++++++- src/main/java/mate/academy/Main.java | 14 +++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/main/java/mate/academy/AsyncRequestProcessor.java b/src/main/java/mate/academy/AsyncRequestProcessor.java index ee5eea1..8f7a6ae 100644 --- a/src/main/java/mate/academy/AsyncRequestProcessor.java +++ b/src/main/java/mate/academy/AsyncRequestProcessor.java @@ -1,16 +1,41 @@ 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 cachedData = cache.get(userId); + if (cachedData != null) { + return CompletableFuture.completedFuture(cachedData); + } + + return CompletableFuture.supplyAsync(() -> { + simulateDelay(); + + UserData userData = + new UserData(userId, "Szczegóły dla użytkownika " + userId); + + cache.put(userId, userData); + return userData; + }, executor); + } + + private void simulateDelay() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } } } diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index a3c9b9e..1ef71f0 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -2,24 +2,24 @@ 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 - AsyncRequestProcessor asyncRequestProcessor = new AsyncRequestProcessor(executor); + 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++) { String userId = userIds[i]; futures[i] = asyncRequestProcessor.processRequest(userId) - .thenAccept(userData -> System.out.println("Processed: " + userData)); + .thenAccept(userData -> + System.out.println("Przetworzono: " + userData)); } - // Wait for all futures to complete CompletableFuture.allOf(futures).join(); executor.shutdown(); } From 3eb8ffcae1c772550f1acbebfb8d73d9e96ae5cb Mon Sep 17 00:00:00 2001 From: Jacek Kubiak Date: Tue, 10 Feb 2026 08:41:44 +0100 Subject: [PATCH 2/3] Task to check again --- .../mate/academy/AsyncRequestProcessor.java | 23 +++++++------------ src/main/java/mate/academy/Main.java | 16 +++++++------ src/main/java/mate/academy/UserData.java | 1 - 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/main/java/mate/academy/AsyncRequestProcessor.java b/src/main/java/mate/academy/AsyncRequestProcessor.java index 8f7a6ae..bb0026d 100644 --- a/src/main/java/mate/academy/AsyncRequestProcessor.java +++ b/src/main/java/mate/academy/AsyncRequestProcessor.java @@ -8,27 +8,20 @@ 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 cachedData = cache.get(userId); - if (cachedData != null) { - return CompletableFuture.completedFuture(cachedData); - } - - return CompletableFuture.supplyAsync(() -> { - simulateDelay(); - - UserData userData = - new UserData(userId, "Szczegóły dla użytkownika " + userId); - - cache.put(userId, userData); - return userData; - }, executor); + return cache.computeIfAbsent(userId, id -> + CompletableFuture.supplyAsync(() -> { + simulateDelay(); + return new UserData(id, "Details for " + id); + }, executor) + ); } private void simulateDelay() { diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index 1ef71f0..d6f4277 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -7,20 +7,22 @@ public class Main { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(4); - AsyncRequestProcessor asyncRequestProcessor = - new AsyncRequestProcessor(executor); + AsyncRequestProcessor processor = new AsyncRequestProcessor(executor); String[] userIds = {"user1", "user2", "user3", "user1"}; - CompletableFuture[] futures = new CompletableFuture[userIds.length]; + CompletableFuture[] futures = + new CompletableFuture[userIds.length]; for (int i = 0; i < userIds.length; i++) { - String userId = userIds[i]; - futures[i] = asyncRequestProcessor.processRequest(userId) - .thenAccept(userData -> - System.out.println("Przetworzono: " + userData)); + futures[i] = processor.processRequest(userIds[i]); } CompletableFuture.allOf(futures).join(); + + for (CompletableFuture future : futures) { + System.out.println("Przetworzono: " + future.join()); + } + executor.shutdown(); } } diff --git a/src/main/java/mate/academy/UserData.java b/src/main/java/mate/academy/UserData.java index ef80432..fcd932a 100644 --- a/src/main/java/mate/academy/UserData.java +++ b/src/main/java/mate/academy/UserData.java @@ -1,5 +1,4 @@ package mate.academy; public record UserData(String userId, String details) { - } From 351436da67b3f1d45094c13b35a406f615ac0f05 Mon Sep 17 00:00:00 2001 From: Jacek Kubiak Date: Tue, 10 Feb 2026 08:53:04 +0100 Subject: [PATCH 3/3] Task to check again2 --- .../mate/academy/AsyncRequestProcessor.java | 18 +++++++++++++++--- src/main/java/mate/academy/Main.java | 15 ++++----------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/main/java/mate/academy/AsyncRequestProcessor.java b/src/main/java/mate/academy/AsyncRequestProcessor.java index bb0026d..ebb4f30 100644 --- a/src/main/java/mate/academy/AsyncRequestProcessor.java +++ b/src/main/java/mate/academy/AsyncRequestProcessor.java @@ -8,7 +8,9 @@ public class AsyncRequestProcessor { private final Executor executor; - private final Map> cache = + + private final Map cache = new ConcurrentHashMap<>(); + private final Map> inFlight = new ConcurrentHashMap<>(); public AsyncRequestProcessor(Executor executor) { @@ -16,11 +18,21 @@ public AsyncRequestProcessor(Executor executor) { } public CompletableFuture processRequest(String userId) { - return cache.computeIfAbsent(userId, id -> + UserData cached = cache.get(userId); + if (cached != null) { + return CompletableFuture.completedFuture(cached); + } + + return inFlight.computeIfAbsent(userId, id -> CompletableFuture.supplyAsync(() -> { simulateDelay(); return new UserData(id, "Details for " + id); - }, executor) + }, executor).whenComplete((result, error) -> { + inFlight.remove(id); + if (error == null) { + cache.put(id, result); + } + }) ); } diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index d6f4277..80dcc34 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -1,6 +1,5 @@ package mate.academy; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -10,17 +9,11 @@ public static void main(String[] args) { AsyncRequestProcessor processor = new AsyncRequestProcessor(executor); String[] userIds = {"user1", "user2", "user3", "user1"}; - CompletableFuture[] futures = - new CompletableFuture[userIds.length]; - for (int i = 0; i < userIds.length; i++) { - futures[i] = processor.processRequest(userIds[i]); - } - - CompletableFuture.allOf(futures).join(); - - for (CompletableFuture future : futures) { - System.out.println("Przetworzono: " + future.join()); + for (String userId : userIds) { + processor.processRequest(userId) + .thenAccept(result -> + System.out.println("Processed: " + result)); } executor.shutdown();