Bootstrap

ThreadPoolExecutor中的RejectedExecutionHandler浅析

当ThreadPoolExecutor中的线程都已经忙于执行,且有界队列也满了,这个时候就需要自己写reject策略;此处给一个demo,供大家去理解和参考:

1、先写一个可执行的线程

package zhengchao_001_005.ThreadPoolExecutor;

public class Task implements Runnable{

	private int id ;
	private String name ;
	
	public Task(int id, String name){
		this.id = id;
		this.name = name;
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public void run() {
		//
		System.out.println("当前线程id和名称为:" + this.id +", " + this.name);
		try {
			Thread.sleep(5*1000);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	public String toString(){
		return "{ id : " + this.id + ", name : " + this.name + "}";
	}
	

}

2、我们写一个RejectedExecutionHandler,必须要实现RejectedExecutionHandler接口,并实现他的rejectedExecution()方法

两个参数,一个是需要拒绝的线程,另一个是我们的线程池,至于如何拒绝,按照自己的业务逻辑去进行处理,

package zhengchao_001_005.ThreadPoolExecutor;

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

public class MyRejected implements RejectedExecutionHandler{

	@Override
	public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
		System.out.println("自定义拒绝处理_"+r.toString());
	}

}

3、测试用例

package zhengchao_001_005.ThreadPoolExecutor;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TestThreadPoolExecutor {

	
	public static void main(String[] args) {
		
		ThreadPoolExecutor pool = new ThreadPoolExecutor(
				1, 				//核心的线程数量
				1, 				//最大的线程数量
				10, 			//空闲数值 
				TimeUnit.SECONDS, 	//空闲时间单位
				new ArrayBlockingQueue<Runnable>(3),//有界队列
				new MyRejected()
				); 			
		
		Task t1 = new Task(1, "任务" + 1);
		Task t2 = new Task(2, "任务" + 2);
		Task t3 = new Task(3, "任务" + 3);
		Task t4 = new Task(4, "任务" + 4);
		Task t5 = new Task(5, "任务" + 5);
		pool.execute(t1);
		pool.execute(t2);
		pool.execute(t3);
		pool.execute(t4);
		pool.execute(t5);
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}		
		//System.out.println(pool.getQueue().size());
		try {
			Thread.sleep(6000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	
	}
}

运行结果:

自定义拒绝处理_{ id : 5, name : 任务5}
当前线程id和名称为:1, 任务1
当前线程id和名称为:2, 任务2
当前线程id和名称为:3, 任务3
当前线程id和名称为:4, 任务4

注意点:

如果使用LinkedBlockingQueue则不会有队列满的问题,LinkedBlockingQueue直到系统资源耗尽才会出问题,但这种体验可能会比较差,至于用哪种好,仁者见仁,不是,业务为前提。


;