CodexBloom - Programming Q&A Platform

Unexpected Behavior of Java 14's CompletableFuture When Using a Custom Executor

👀 Views: 36 đŸ’Ŧ Answers: 1 📅 Created: 2025-08-29
java concurrency completablefuture Java

I've tried everything I can think of but I'm currently working on a multi-threaded application using Java 14 where I'm trying to execute several async tasks using `CompletableFuture`. However, I'm experiencing unexpected behavior when I provide a custom executor to the `supplyAsync` method. Specifically, when the executor has a limited thread pool, the tasks do not seem to execute as expected and sometimes result in a `RejectedExecutionException`. Below is a simplified version of my code: ```java import java.util.concurrent.*; public class AsyncExample { private static final int THREAD_POOL_SIZE = 2; private static final ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE); public static void main(String[] args) { CompletableFuture<Void> future1 = CompletableFuture.supplyAsync(() -> { System.out.println("Task 1 executing"); return "Result 1"; }, executor); CompletableFuture<Void> future2 = CompletableFuture.supplyAsync(() -> { System.out.println("Task 2 executing"); return "Result 2"; }, executor); CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2); combinedFuture.join(); executor.shutdown(); } } ``` When I run the above code, I expect both tasks to execute concurrently, but I sometimes get the following error message: ``` Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.CompletableFuture$AsyncSupply@5e91993f rejected from java.util.concurrent.ThreadPoolExecutor@6d06d69c[Terminated, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 2] ``` I've tried increasing the `THREAD_POOL_SIZE`, which does allow more tasks to run simultaneously, but I also want to limit the number of concurrent tasks for resource management, especially when interacting with external APIs. Am I misunderstanding how to properly use a custom executor with `CompletableFuture`, or is there a better approach to manage this scenario? Any insights would be greatly appreciated! Any suggestions would be helpful.