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直到系統資源耗盡纔會出問題,但這種體驗可能會比較差,至於用哪種好,仁者見仁,不是,業務爲前提。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章