Table of Contents
1. Introduction
Java’s
Executors.newCachedThreadPool()
factory method provides a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. Our goal is to understand how to use this thread pool to execute asynchronous tasks efficiently.2. What is newCachedThreadPool?
The
newCachedThreadPool
method from the java.util.concurrent.Executors
class is a factory method that creates a unbounded thread pool. It sets maximum pool size to Integer.Max
. This thread pool can dynamically adjust to the workload by creating new threads as needed and reusing idle threads. Threads that have not been used for 60 seconds are terminated and removed from the cache, making this thread pool ideal for executing short-lived asynchronous tasks.3. Executors.newCachedThreadPool() Example
Let’s create a Task. Here Task will be to read different files and process them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class FetchDataFromFile implements Runnable{ private final String fileName; public FetchDataFromFile(String fileName) { super(); this.fileName = fileName; } @Override public void run() { try { System.out.println("Fetching data from "+fileName+" by "+Thread.currentThread().getName()); Thread.sleep(5000); // Reading file System.out.println("Read file successfully: "+fileName+" by "+Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } public String getFileName() { return fileName; } } |
Let’s create a ThreadPoolExecutor that will consume the task mentioned above and process it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; public class ThreadPoolExecutorMain { public static void main(String args[]) { // Getting instance of ThreadPoolExecutor using Executors.newCachedThreadPool factory method ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); for (int i = 1; i <= 10; i++) { FetchDataFromFile fdff = new FetchDataFromFile("File :" + i); System.out.println("A new file has been added to read : " + fdff.getFileName()); threadPoolExecutor.execute(fdff); } threadPoolExecutor.shutdown(); } } |
When you run above program, you will get below output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
A new file has been added to read : File :1 A new file has been added to read : File :2 Fetching data from File :1 by pool-1-thread-1 Fetching data from File :2 by pool-1-thread-2 A new file has been added to read : File :3 A new file has been added to read : File :4 Fetching data from File :3 by pool-1-thread-3 Fetching data from File :4 by pool-1-thread-4 A new file has been added to read : File :5 Fetching data from File :5 by pool-1-thread-5 A new file has been added to read : File :6 Fetching data from File :6 by pool-1-thread-6 A new file has been added to read : File :7 Fetching data from File :7 by pool-1-thread-7 A new file has been added to read : File :8 A new file has been added to read : File :9 Fetching data from File :8 by pool-1-thread-8 A new file has been added to read : File :10 Fetching data from File :9 by pool-1-thread-9 Fetching data from File :10 by pool-1-thread-10 |
newCachedThreadPool
is a good choice when you want better queuing performance than what is offered by newFixedThreadPool. If you want to restrict the number of concurrent tasks for resource management, go with newFixedThreadPool.
Here is flow for the program:
- The program starts and initializes the thread pool using
Executors.newCachedThreadPool()
. - For each file from 1 to 10, a new
FetchDataFromFile
task is created and submitted to the thread pool. - The thread pool assigns threads to execute these tasks. Each task simulates reading a file by sleeping for 5 seconds.
- As tasks are executed, messages are printed to indicate the start and completion of file reading.
- After all tasks have been submitted, the thread pool is shut down.
4. Difference between newFixedThreadPool() and newCacheThreadPool() Factory Methods
- Thread Count:
newFixedThreadPool
maintains a fixed number of threads, whilenewCachedThreadPool
creates threads as needed and removes them when they’re idle. - Queueing Behavior:
newFixedThreadPool
queues tasks when all threads are busy, leading to potential memory issues with a large number of tasks.newCachedThreadPool
minimizes queuing by creating new threads as needed. - Use Cases:
newFixedThreadPool
is suitable for applications with a known, limited concurrency level, whereasnewCachedThreadPool
is better for handling a large number of short-lived tasks efficiently.
5. Conclusion
The newCachedThreadPool
method offers a highly efficient way to handle concurrent tasks, especially when dealing with numerous short-lived asynchronous tasks. It outperforms the simple thread creation approach by reusing threads, which reduces the overhead and increases performance. Utilizing newCachedThreadPool
in Java applications can lead to more efficient and scalable concurrency management.
Was this post helpful?
Let us know if this post was helpful. Feedbacks are monitored on daily basis. Please do provide feedback as that\'s the only way to improve.