java線程池工作隊列飽和策略代碼示例

線程池(Thread Pool) 是并行執(zhí)行任務收集的實用工具。隨著 CPU 引入適合于應用程序并行化的多核體系結構,線程池的作用正日益顯現(xiàn)。通過 ThreadPoolExecutor類及其他輔助類,Java 5 引入了這一框架,作為新的并發(fā)支持部分。

創(chuàng)新互聯(lián)公司成立于2013年,是專業(yè)互聯(lián)網技術服務公司,擁有項目成都網站設計、做網站網站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元長汀做網站,已為上家服務,為長汀各地企業(yè)和個人服務,聯(lián)系電話:028-86922220

ThreadPoolExecutor框架靈活且功能強大,它支持特定于用戶的配置并提供了相關的掛鉤(hook)和飽和策略來處理滿隊列

Java線程池會將提交的任務先置于工作隊列中,在從工作隊列中獲取(SynchronousQueue直接由生產者提交給工作線程)。那么工作隊列就有兩種實現(xiàn)策略:無界隊列和有界隊列。無界隊列不存在飽和的問題,但是其問題是當請求持續(xù)高負載的話,任務會無腦的加入工作隊列,那么很可能導致內存等資源溢出或者耗盡。而有界隊列不會帶來高負載導致的內存耗盡的問題,但是有引發(fā)工作隊列已滿情況下,新提交的任務如何管理的難題,這就是線程池工作隊列飽和策略要解決的問題。

飽和策略分為:Abort 策略, CallerRuns 策略,Discard策略,DiscardOlds策略。

為了更好的理解,我編寫一個小的例子。

package concurrency.pool;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class SaturationPolicy {
	/**
   * 線程池工作隊列已滿時,在不同飽和策略下表現(xiàn)
   * @param handler 線程池工作隊列飽和策略
   */
	public static void policy(RejectedExecutionHandler handler){
		//基本線程2個,最大線程數(shù)為3,工作隊列容量為5
		ThreadPoolExecutor exec = new ThreadPoolExecutor(2,3,0l, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>(5));
		if (handler != null){
			exec.setRejectedExecutionHandler(handler);
			//設置飽和策略
		}
		for (int i = 0; i < 10; i++) {
			exec.submit(new Task());
			//提交任務
		}
		exec.shutdown();
	}
	public static void main(String[] args) {
		//    policy(new ThreadPoolExecutor.AbortPolicy());
		//    policy((new ThreadPoolExecutor.CallerRunsPolicy()));
		//    policy(new ThreadPoolExecutor.DiscardPolicy());
		//    policy(new ThreadPoolExecutor.DiscardOldestPolicy());
	}
	//自定義任務
	static class Task implements Runnable {
		private static int count = 0;
		private int id = 0;
		//任務標識
		public Task() {
			id = ++count;
		}
		@Override
		    public void run() {
			try {
				TimeUnit.SECONDS.sleep(3);
				//休眠3秒
			}
			catch (InterruptedException e) {
				System.err.println("線程被中斷" + e.getMessage());
			}
			System.out.println(" 任務:" + id + "\t 工作線程: "+ Thread.currentThread().getName() + " 執(zhí)行完畢");
		}
	}
}

當工作隊列滿了,不同策略的處理方式為:

1.Abort策略:默認策略,新任務提交時直接拋出未檢查的異常RejectedExecutionException,該異常可由調用者捕獲。
在主函數(shù)中添加如下代碼:

policy(new ThreadPoolExecutor.AbortPolicy()); 

運行結果為:

java線程池工作隊列飽和策略代碼示例

程序拋出了RejectedExecutionException,并且一共運行了8個任務(線程池開始能運行3個任務,工作隊列中存儲5個隊列)。當工作隊列滿了的時候,直接拋出了異常,而且JVM一直不退出(我現(xiàn)在也不知道什么原因)。我們可以看到執(zhí)行任務的線程全是線程池中的線程。

2.CallerRuns策略:為調節(jié)機制,既不拋棄任務也不拋出異常,而是將某些任務回退到調用者。不會在線程池的線程中執(zhí)行新的任務,而是在調用exector的線程中運行新的任務。

在主函數(shù)運行:

policy((new ThreadPoolExecutor.CallerRunsPolicy())); 

運行結果

java線程池工作隊列飽和策略代碼示例

所有的任務都被運行,且有2(10 - 3 -5)個任務是在main線程中執(zhí)行成功的,8個任務在線程池中的線程執(zhí)行的。
3.Discard策略:新提交的任務被拋棄。
在main函數(shù)中運行

policy(new ThreadPoolExecutor.DiscardPolicy()); 

java線程池工作隊列飽和策略代碼示例

通過上面的結果可以顯示:沒有異常拋出,后面提交的2個新任務被拋棄,只處理了前8(3+5)個任務,JVM退出。

4.DiscardOldest策略:隊列的是“隊頭”的任務,然后嘗試提交新的任務。(不適合工作隊列為優(yōu)先隊列場景)

在main函數(shù)中運行如下方法

policy(new ThreadPoolExecutor.DiscardOldestPolicy()); 

運行結果:一共運行8個任務,程序結束,后面添加的任務9,任務10被執(zhí)行了,而前面的任務3,任務4被丟棄。

java線程池工作隊列飽和策略代碼示例

總結

以上就是本文關于java線程池工作隊列飽和策略代碼示例的全部內容,希望對大家有所幫助。如有不足之處,歡迎留言指出。感謝朋友們對本站的支持。

網站名稱:java線程池工作隊列飽和策略代碼示例
本文鏈接:http://www.muchs.cn/article18/gehcdp.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供App設計、網站制作、網站內鏈、網站營銷、網站排名、網站維護

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

商城網站建設