RejectedExecutionHandler

java.util.concurrent.RejectedExecutionHandler Example

Here we will discuss about the RejectedExecutionHandler Interface in the java.util.concurrent package. This interface is really helpfull when working with the ThreadPoolExecutor.

1. Overview & Usage

The interface java.util.concurrent.RejectedExecutionHandler is a handler for tasks that cannot be executed by a ThreadPoolExecutor ( a class that implements ExecutorService, ). This may occur when no more threads or queue slots are available because their bounds(limit of its local “memory”) would be exceeded, or upon shutdown of the Executor. The known implementation of the Interface are: ThreadPoolExecutor.AbortPolicy, ThreadPoolExecutor.CallerRunsPolicy, ThreadPoolExecutor.DiscardOldestPolicy, ThreadPoolExecutor.DiscardPolicy. First let us have a look to the Interface declaration:

public interface RejectedExecutionHandler {
 void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}

1.1 The rejectedExecution(Runnable r,ThreadPoolExecutor e) method:

New tasks submitted in method execute(java.lang.Runnable) will be rejected when the Executor has been shut down, and also when no more threads or queue slots are available because their bounds(limit of its local “memory”) would be exceeded. In either case, the execute method invokes the RejectedExecutionHandler.rejectedExecution(Runnable r,ThreadPoolExecutor e) method of its RejectedExecutionHandler. If no other alternative is available then it’s implementation may throw an unchecked RejectedExecutionException, which will be propagated to the caller of execute().

2. Example

In order to show the use of the RejectedExecutionHandler we have to use a  ThreadPoolExecutor to execute a number of worker threads. Let’s see how you can do that.

Here a simple worker thread:

Worker.java:

package com.javacodegeeks.example.rivu.rejectedexecutionhandlerexample;

public class Worker implements Runnable {

	int id;
	String name="Worker";
	
	public Worker(int id)
	{
		this.id=id;
		System.out.println("Worker "+id+" Created");
		
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		Thread curThread = Thread.currentThread(); 
		try{
	            name=curThread.getName();
				System.out.println(name + " Executing " + id);
	            Thread.sleep(1000);
	            System.out.println(name + " Completed " + id);
	        }
	     catch(Exception e){
	     System.out.println(e.getMessage());
	         }
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		String s=name+" ID: "+id;
		return s;
	}
	
	 

}

The class in which we implemented the RejectedExecutionHandler.

MyRejectedExecutionHandler.java:

package com.javacodegeeks.example.rivu.rejectedexecutionhandlerexample;


import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

public class MyRejectedExecutionHandler implements RejectedExecutionHandler {

	
	
	@Override
	public void rejectedExecution(Runnable worker, ThreadPoolExecutor executor) {
		// TODO Auto-generated method stub
		System.out.println(worker.toString()+" is Rejected");
		
		System.out.println("Retrying to Execute");
		try{
			//Re-executing with alternateExecutor
			RejectedExecutionHandlerExample.alternateExecutor.execute(worker);
			System.out.println(worker.toString()+" Execution Started");
		}
		catch(Exception e)
		{
			System.out.println("Failure to Re-exicute "+e.getMessage());
		}
	}

}

RejectedExecutionHandlerExample.java:

package com.javacodegeeks.example.rivu.rejectedexecutionhandlerexample;

import java.util.concurrent.*;
import java.util.concurrent.ThreadPoolExecutor;

public class RejectedExecutionHandlerExample {

	public static ThreadPoolExecutor executor=(ThreadPoolExecutor) Executors.newFixedThreadPool(5);
	public static ThreadPoolExecutor alternateExecutor=(ThreadPoolExecutor) Executors.newFixedThreadPool(5);
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		RejectedExecutionHandler handler=new MyRejectedExecutionHandler();
		executor.setRejectedExecutionHandler(handler);
		
		
		System.out.println("Starting ThreadPoolExecutor");
		
		Worker[] workers=new Worker[10];
		for(int i=0;i<10;i++){
			workers[i]=new Worker(i);
			executor.execute(workers[i]);
			if(i==6)
				executor.shutdown();// The executor is terminated intentionally to check the RejectedExecutionHandler
		}
		executor.shutdown();
		while(!executor.isTerminated()){
			//Waiting for the termination of executor
		}
		System.out.println("Execution Completed");
		
		alternateExecutor.shutdown();
		while(!alternateExecutor.isTerminated()){
			//Waiting for the termination of alternateExecutor
		}
		System.out.println("Alternate Execution Completed");
	}

}

Output

Starting ThreadPoolExecutor
Worker 0 Created
Worker 1 Created
Worker 2 Created
Worker 3 Created
pool-1-thread-2 Executing 1
pool-1-thread-1 Executing 0
Worker 4 Created
pool-1-thread-3 Executing 2
pool-1-thread-4 Executing 3
Worker 5 Created
pool-1-thread-5 Executing 4
Worker 6 Created
Worker 7 Created
Worker ID: 7 is Rejected
Retrying to Execute
Worker ID: 7 Execution Started
Worker 8 Created
Worker ID: 8 is Rejected
Retrying to Execute
pool-2-thread-1 Executing 7
Worker ID: 8 Execution Started
Worker 9 Created
Worker ID: 9 is Rejected
Retrying to Execute
pool-2-thread-2 Executing 8
Worker ID: 9 Execution Started
pool-2-thread-3 Executing 9
pool-1-thread-2 Completed 1
pool-1-thread-3 Completed 2
pool-1-thread-1 Completed 0
pool-1-thread-1 Executing 5
pool-1-thread-2 Executing 6
pool-1-thread-4 Completed 3
pool-1-thread-5 Completed 4
pool-2-thread-1 Completed 7
pool-2-thread-2 Completed 8
pool-2-thread-3 Completed 9
pool-1-thread-1 Completed 5
pool-1-thread-2 Completed 6
Execution Completed
Alternate Execution Completed

2.1 Conclusion

When we submit submit a task to the ThreadPoolExecutor then following sequence of event happens:

  • If there is any worker thread free which is free and can run this task.
  • Else it will try to move this task to the workerqueue from where a worker thread will pick up the task if it is free.
  • If the workerQueue is also full then it will try to create a new thread if possible(no of worker threads are less than maxPoolSize).
  • If all the above fails then the task is sent to the handler.

In this example the RejectedExecutionHandlerExample.java I intentionally shutdown() the executor, as a result of this the executor rejects all new tasks, which are efficiently handled using the MyRejectedExecutionHandler. If the alternateExecutor also fails to executor the tasks then it will throw a RejectedExecutionException which will be caught by the catch block in the MyRejectedExecutionHandler.java.

3. Download

It was an Example on RejectedExecutionHandler. Download the Eclipse project of this tutorial:

Download
You can download the full source code of this example here : RejectedExecutionHandler Example.zip

Rivu Chakraborty

Rivu Chakraborty is a Google Certified Android Developer, Sr. Tech Member of Institute of Engineers (India), he also have certifications on Scrum. He is also an author of multiple books on Kotlin, Reactive Programming, Functional Programming and Android Development, published by renowned publication houses. Having total 5+ years of experience he is presently working as a Sr. Software Engineer (Android) at Indus Net Technologies Pvt. Ltd. Rivu Chakraborty considers himself a Kotlin and Android enthusiast and a Kotlin evangelist. He has been using Kotlin since December 2015, so he has around 2 years' experience in Kotlin. As part of his mission to expand the use and knowledge of the Kotlin Language as much as possible, he created the KotlinKolkata User Group, one of the most active Kotlin user groups throughout the world and he is a Founder Organizer of KotlinKolkata. He is also an active member of GDG Kolkata and gives talks at GDG Kolkata Meetups.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button