Existing Fixed Pool Threads ExecutorService
I am using the following piece of code in our code.
ExecutorService executor = Executors.newFixedThreadPool(4);
while(loop 50 times){
//In the extreme case I will have 50 threads and only 4 will be active and remaining are in queue
MyThread myThread = new MyThread();
executor.execute(myThread);//Each Thread process 100,000 records and put in a file
}
executor.shutdown();
while (!executor.isTerminated()) {
}
Here are my questions:
- It hangs in the second loop. What could be the reason?
- Is there any way to terminate the entire thread pool at a specific interval?
- Is it possible to complete the stream after a certain amount of time?
Please help me with this.
source to share
1. It hangs in the second loop. What could be the reason?
The reason for the hang may be due to a very small number of threads compared to the number of records that need to be processed and stored in the file. If each thread had to process 100,000 records and put into a file, then 50 thread tasks, shared by four threads, would process 5,000,000 records with 50 files. Therefore, it is better to increase the number of threads and check. Also take note of the time taken by each thread to effectively measure if you are reducing the time spent overall by increasing the number of fixed pool threads.
2. Is there any way to terminate the whole thread pool after a certain interval?
Yes below code shows that: -
executor.shutdown();
executor.awaitTermination(60, TimeUnit.SECONDS); // blocks/waits for certain interval as specified
executor.shutdownNow(); // Forcefully terminate entire thread pool after the above time.
3. Can I end the stream after a certain amount of time?
Yes, as long as the effective reason for terminating the thread is to stop some task. To achieve this, we need to get a reference to the future and wait conditionally for a period of time before we decisively cancel the task and abort the thread that is doing the task.
Map<String, Future> tasks = new HashMap<String, Future>();
while(i++ < 50){
//In the extreme case I will have 50 threads and only 4 will be active and remaining are in queue
Thread myThread = new Thread();
tasks.put("Thread"+i ,executor.submit(myThread));//Each Thread process 100,000 records and put in a file
}
// say you want to terminate Thread2 after 60 seconds
Future thread2Task = tasks.get("Thread2");
thread2Task.get(60, TimeUnit.SECONDS);
thread2Task.cancel(true); // boolean whether you want to interrupt the thred forcefully
source to share
The ExecutorServise will have a pool of threads to execute your Runnable tasks, you defined the pool size to 4, I would change that as the number of processors in the machine:
int threadCount = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
Also, it looks like you are sending Threads to the executors to execute them in one of the available threads in the pool, it is redundant, you can change your MyThread task to Runnable.
source to share
You are doing it wrong. The thread pool always accepts a runnable object. Although the thread class implements an executable interface, and it does not accept a thread class object. You need to declare a running object and then give it a thread class object through polymorphic behavior, it will start the thread.
You need to do this:
ExecutorService name = Executors.newFixedThreadPool(no of threads yu want);
for(i = 0 ; i < no of threads ; i++)
{
Runnable runnable = new MyThread();
name.execute(runnable)
}
\\ now you can terminate the thread like this. if you want
\\ to wait then you can use
\\executor.awaitTermination(60, TimeUnit.SECONDS);
executor.shutdown();
while(!executor.isTerminated()) {}
System.out.println("Finished all the worker threads");
source to share