In the previous post "ThreadPoolexecutor in Java" we created our user defined RejectedHandler,which will be invoked if any task is rejected by the ThreadPoolExecutor.In addition to defining user defined RejectedHandler,ThreadPoolExecutor provides four predefined handler polices for handling the rejected task:
- ThreadPoolExecutor.AbortPolicy
- ThreadPoolExecutor.CallerRunsPolicy
- ThreadPoolExecutor.DiscardPolicy
- ThreadPoolExecutor.DiscardOldestPolicy
If you remember the program used in the post ThreadPoolExecutor in Java we created the ThreadPool in the method createThreadPool and the user defined Rejected Handler was used in the
ThreadPool as shown below:
private void createThreadPool() {
int poolSize=2;
int maxPoolSize=5;
int queueSize=3;
long aliveTive=1000;
ArrayBlockingQueue<Runnable> queue= new ArrayBlockingQueue<Runnable>(queueSize);
threadPoolExecutor= new ThreadPoolExecutor(poolSize,maxPoolSize,aliveTive,
TimeUnit.MILLISECONDS,queue,new JobRejectionHandler());
}
|
When we run the program,we will get the below output.The below output shows that the rejected task
were handled through our defined Rejection Handler JobRejectionHandler.
Output For User defined Handler:
JobId:Job1 Running through Thread:pool-1-thread-1
JobId:Job2 Running through Thread:pool-1-thread-2
JobId:Job9 Running through RejectionHandler,Since there are no ideal threads in ThreadPool
JobId:Job10 Running through RejectionHandler,Since there are no ideal threads in ThreadPool
JobId:Job6 Running through Thread:pool-1-thread-3
JobId:Job7 Running through Thread:pool-1-thread-4
JobId:Job8 Running through Thread:pool-1-thread-5
JobId:Job3 Running through Thread:pool-1-thread-1
JobId:Job4 Running through Thread:pool-1-thread-2
JobId:Job5 Running through Thread:pool-1-thread-3
We will use the predefined handler policies while creating the ThreadPool in method createThreadPool() and will see how the output varies for each of the rejection policies.
1)ThreadPoolExecutor.AbortPolicy
By using this handler policy in ThreadPoolExecutor,the handler will throw the exception RejectedExecutionException if any task is rejected by the Threadpool. Change the method createThreadPool() to have the ThreadPoolExecutor.AbortPolicy as the handler policy as shown below and run the program.
private void createThreadPool() {
int poolSize=2;
int maxPoolSize=5;
int queueSize=3;
long aliveTive=1000;
ArrayBlockingQueue<Runnable> queue= new ArrayBlockingQueue<Runnable>(queueSize);
threadPoolExecutor= new ThreadPoolExecutor(poolSize,maxPoolSize,aliveTive,
TimeUnit.MILLISECONDS,queue,new ThreadPoolExecutor.AbortPolicy());
}
|
Output for AbortPolicy:
JobId:Job1 Running through Thread:pool-1-thread-1
JobId:Job2 Running through Thread:pool-1-thread-2
JobId:Job6 Running through Thread:pool-1-thread-3
JobId:Job7 Running through Thread:pool-1-thread-4
Exception in thread "main" java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.reject(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.execute(Unknown Source)
at ThreadPoolExample.submitTask(ThreadPoolExample.java:43)
at ThreadPoolExample.main(ThreadPoolExample.java:19)
JobId:Job8 Running through Thread:pool-1-thread-5
JobId:Job3 Running through Thread:pool-1-thread-1
JobId:Job4 Running through Thread:pool-1-thread-2
JobId:Job5 Running through Thread:pool-1-thread-3
As we can see in the above output the task Job9 and Job10 were rejected by the ThreadPool and hence
the RejectedExecutionException was thrown.
2)ThreadPoolExecutor.CallerRunsPolicy
By using this handler policy in ThreadPool,the handler will invoke the rejected task in the thread which called the execute method i.e the Caller which added this task to the ThreadPool. Change the method createThreadPool() to have the ThreadPoolExecutor.CallerRunsPolicy as the handler policy and
run the program.This handler will slowdown the task addition to the ThreadPool if there is any rejected task since the caller(which adds the task to ThreadPool) will run the rejected task.
private void createThreadPool() {
int poolSize=2;
int maxPoolSize=5;
int queueSize=3;
long aliveTive=1000;
ArrayBlockingQueue<Runnable> queue= new ArrayBlockingQueue<Runnable>(queueSize);
threadPoolExecutor= new ThreadPoolExecutor(poolSize,maxPoolSize,aliveTive,
TimeUnit.MILLISECONDS,queue,new ThreadPoolExecutor.CallerRunsPolicy())
}
|
Output for CallerRunsPolicy:
JobId:Job1 Running through Thread:pool-1-thread-1
JobId:Job2 Running through Thread:pool-1-thread-2
JobId:Job9 Running through Thread:main
JobId:Job6 Running through Thread:pool-1-thread-3
JobId:Job7 Running through Thread:pool-1-thread-4
JobId:Job8 Running through Thread:pool-1-thread-5
JobId:Job3 Running through Thread:pool-1-thread-1
JobId:Job4 Running through Thread:pool-1-thread-2
JobId:Job5 Running through Thread:pool-1-thread-3
JobId:Job10 Running through Thread:pool-1-thread-4
As we can see in the above output the task Job9 were rejected by the ThreadPool and the handler ran
it through the Main thread since the Main Thread is the one which added the task to the ThreadPool. Also we can notice that the task Job10 was not rejected by the ThreadPool. It is due to the slowness in adding the task to the ThreadPool,since the caller i.e Main Thread has run the rejected task Job 9 and by the time Job10 was added ,an ideal thread in the pool was found to run the task.
3)ThreadPoolExecutor.DiscardPolicy
This handler will silently discards the rejected task and will not take any action for the rejected task.Change the method createThreadPool() to have the ThreadPoolExecutor.DiscardPolicy as the handler policy and run the program.
private void createThreadPool() {
int poolSize=2;
int maxPoolSize=5;
int queueSize=3;
long aliveTive=1000;
ArrayBlockingQueue<Runnable> queue= new ArrayBlockingQueue<Runnable>(queueSize);
threadPoolExecutor= new ThreadPoolExecutor(poolSize,maxPoolSize,aliveTive,
TimeUnit.MILLISECONDS,queue,new ThreadPoolExecutor.DiscardPolicy());
}
|
Output for DiscardPolicy:
JobId:Job1 Running through Thread:pool-1-thread-1
JobId:Job2 Running through Thread:pool-1-thread-2
JobId:Job6 Running through Thread:pool-1-thread-3
JobId:Job7 Running through Thread:pool-1-thread-4
JobId:Job8 Running through Thread:pool-1-thread-5
JobId:Job3 Running through Thread:pool-1-thread-1
JobId:Job4 Running through Thread:pool-1-thread-2
JobId:Job5 Running through Thread:pool-1-thread-3
As we can see in the above output the rejected task Job9 and Job10 were silently discarded by the handler and were no action taken by the handler.
4)ThreadPoolExecutor.DiscardOldestPolicy
If any added task is about to be rejected,the handler will discards the oldest unallocated task until it finds the ideal thread and then execute the current task through the ideal thread.Change the method createThreadPool() to have the ThreadPoolExecutor.DiscardOldestPolicy as the handler policy and run the program.
private void createThreadPool() {
int poolSize=2;
int maxPoolSize=5;
int queueSize=3;
long aliveTive=1000;
ArrayBlockingQueue<Runnable> queue= new ArrayBlockingQueue<Runnable>(queueSize);
threadPoolExecutor= new ThreadPoolExecutor(poolSize,maxPoolSize,aliveTive,
TimeUnit.MILLISECONDS,queue,new ThreadPoolExecutor.DiscardOldestPolicy());
}
|
Output for DiscardOldestPolicy:
JobId:Job1 Running through Thread:pool-1-thread-1
JobId:Job2 Running through Thread:pool-1-thread-2
JobId:Job6 Running through Thread:pool-1-thread-3
JobId:Job7 Running through Thread:pool-1-thread-4
JobId:Job8 Running through Thread:pool-1-thread-5
JobId:Job5 Running through Thread:pool-1-thread-1
JobId:Job9 Running through Thread:pool-1-thread-2
JobId:Job10 Running through Thread:pool-1-thread-3
As we can see in the above output,the ThreadPool discard the task Job 3 and Job 4.This due to:
- Since there were no ideal threads to run the task Job9 and hence the task will handled by the handler.
- The handler then discards the oldest unallocated task which is task Job3 waiting in the queue. Then an ideal thread in the poolwas found to run the task Job9.
- The same apply for Job 10 as well which made the handler to discard the oldest task Job4 and then an ideal thread was found to run the task Job10.
Related Topics:
Very Good Tutorial,Thanks for giving proper reasons after the results
ReplyDeleteWhat happens if rejectedexecutedexception is caught due to the shut down of executor(Object is dereferenced). Will the behavior of handler remains same?
ReplyDeleteIs it possible to print which msg have been discarded
ReplyDeleteNice post
ReplyDelete