Java > Concurrency and Multithreading > Executors and Thread Pools > Creating Executors and Thread Pools
Creating and Using a Fixed Thread Pool Executor
This example demonstrates how to create and use a fixed-size thread pool executor in Java. A fixed thread pool executor maintains a specific number of threads to execute tasks. If all threads are busy, new tasks are placed in a queue until a thread becomes available.
Core Concepts: Fixed Thread Pool Executor
A fixed thread pool uses a fixed number of threads. Tasks are submitted to the pool, and if all threads are currently busy, the tasks are placed in a queue. This approach is useful when you want to limit the number of concurrent operations to prevent resource exhaustion. Key classes involved are ExecutorService
and Executors
.
Code Example: Creating a Fixed Thread Pool
The code creates a fixed thread pool with 3 threads using Executors.newFixedThreadPool(3)
. It then submits 10 tasks to the executor. Each task prints a message indicating which thread is executing it and then sleeps for 1 second. Finally, the executor is shut down using executor.shutdown()
, which prevents new tasks from being submitted but allows already submitted tasks to complete. The while
loop waits for all tasks to finish.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadPoolExample {
public static void main(String[] args) {
// Create a fixed thread pool with 3 threads
ExecutorService executor = Executors.newFixedThreadPool(3);
// Submit tasks to the executor
for (int i = 0; i < 10; i++) {
final int taskNumber = i;
executor.submit(() -> {
System.out.println("Task " + taskNumber + " executed by " + Thread.currentThread().getName());
try {
Thread.sleep(1000); // Simulate some work
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// Shut down the executor
executor.shutdown();
// Wait for all tasks to complete
while (!executor.isTerminated()) {
// Wait until all threads are finished
}
System.out.println("All tasks finished");
}
}
Real-Life Use Case
Fixed thread pools are suitable for scenarios where you need to limit the number of concurrent operations, such as processing incoming requests on a web server or handling a large number of file processing tasks. For example, you might want to restrict the number of concurrent database connections to prevent overloading the database server.
Best Practices
executor.shutdown()
or executor.shutdownNow()
to prevent resource leaks.InterruptedException
properly when tasks are interrupted.try-finally
block to ensure that the executor is always shut down, even if an exception occurs.
Interview Tip
Explain the difference between shutdown()
and shutdownNow()
. shutdown()
prevents new tasks from being submitted but allows already submitted tasks to complete, while shutdownNow()
attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
When to Use a Fixed Thread Pool
Use a fixed thread pool when you need to limit the number of concurrent tasks and want to ensure that the application doesn't consume excessive resources. It's a good choice for tasks that are relatively uniform in their execution time.
Memory Footprint
The memory footprint is determined by the number of threads in the pool and the memory required by each thread's stack. Increasing the pool size increases the memory consumption. Monitor the memory usage to avoid OutOfMemoryError
exceptions.
Alternatives
Alternatives to a fixed thread pool include:
Pros
Cons
FAQ
-
What happens if I submit more tasks than the thread pool size?
If you submit more tasks than the thread pool size, the extra tasks will be placed in a queue until a thread becomes available to execute them. -
How do I determine the optimal thread pool size?
The optimal thread pool size depends on the nature of the tasks. For CPU-bound tasks, a thread pool size equal to the number of CPU cores is often a good starting point. For I/O-bound tasks, a larger thread pool size may be more appropriate. -
What is the difference between
shutdown()
andshutdownNow()
?
shutdown()
prevents new tasks from being submitted but allows already submitted tasks to complete, whileshutdownNow()
attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.