Executors的四種連接池

文章摘抄於《Java併發實戰》121頁

線程池概念

	正如名稱中所稱的那樣,線程池管理一個工作者線程的同構池(homongeneous pool)。線程池是與工作對列(wore queue)緊密綁定的。所謂工作隊列,其作用是持有所有等待執行的任務。工作者線程從工作隊列中獲取下一個任務,執行它,然後回去繼續等待另一個線程。
	在線程池中執行任務線程,這種方法有很多“每任務每線程”無法比擬的優勢。重用存在的線程,而不是創建新的線程。這可以在處理多請求時抵消線程創建、消亡產生的開銷。另一項額外的好處是,在請求到達時,工作者線程通常已經存在,用於創建線程的等待時間不會延遲任務的執,因此提高了響應度。通過適當的調整線程池的大小,你可以得到足夠多的線程以保持處理器忙碌,同時還可以防止過多的線程相互競爭資源,導致應用程序耗盡內存或者失敗。

Executor接口代碼

public interface Executor{
	void execute(Runnable command);
}

四種線程池

	類庫提供了一個靈活的線程池實現和一些有用的預設配置,你可以通過調用Executors中的某種靜態工廠來創建一個線程池:
	(1)newFixedThreadPool創建了定長的線程池,每當提交一個任務就創建一個線程,直到達到池的最大長度,這時線程池會保持長度不再變化(如果一個線程由於非預期的Exception而結束,線程池會補充一個新的線程)。
	(2)newCachedThreadPool創建一個可緩存的線程池,如果當前線程池的長度超過了處理的需要時,它可以靈活地回收空閒地線程。
	(3)newSingleThreadExecutor創建一個單線程化地executor,它只創建唯一的工作者線程來執行任務,如果這個線程異常結束,會有另一個取代它。executor會保證任務依照任務隊列所規定的順序執行。
	(4)newScheduleThreadPool拆概念一個定長的線程池,而且支持定時以及週期性的任務執行,類似於Timer;

Executor的生命週期

	Executor實現通常只是爲了執行任務而創建線程,但是JVM會在所有(非後臺的,nondaemin)線程全部終止後才退出。因此,如果無法正確關閉Executor,將會組織JVM的結束。
	因爲Executor是異步地執行任務,所以在任何時間裏,所有之前提交的任務的狀態都不能立即可見。這些任務中,有可能已經完成,有可能正在運行。其他的還可能在隊列中等待執行。關閉應用程序時,程序會出現很多種情況:從最平緩的關閉(已經啓動的任務全部完成而且沒有再接到任何新的工作)到最唐突的關閉(拔掉機房的電源),以及介於這兩種極端情況之間的各種可能。既然Executor是爲應用程序提供的,他們理應可以關閉,無論是平緩的還是唐突的。另外,關閉操作還會影響到記錄應用程序任務狀態的反饋信息。
	爲了解決這個執行服務的生命週期問題,ExecutorService接口擴展了Executor,並且添加了一些用於生命週期管理的方法(同時還有一些用於任務提交的便利方法)。如下:
public interface ExecutorServiece extends Executor{
	void shutdown();
	List<Runnable> shutdownNow();
	boolean isShutdown();
	boolean isTerminated();
	boolean awaitTermination(long timeout,TimeUnit unit) throws IterruptedException;
}
	ExecutorService暗示了生命週期有3種狀態:運行(running)、關閉(shutting down)和終止(terminated)。ExecutorService最初後的初始狀態是運行狀態。shutdown方法會啓動一個平緩的關閉過程。停止接受新的任務,同時等待已經提交的任務完成---包括尚未開始執行的任務。shutdownNow方法會啓動一個強制的關閉過程,嘗試取消所有運行中的任務和排在隊列中尚未開始的任務。
	在關閉後提交到ExecutorService中的任務,會被拒絕執行處理器(rejected execution handler)處理。拒絕執行處理器(拒絕執行處理器是ExecutorService的一種實現。ThreadPoolExecutor提供的,ExecutorService接口中的方法並不提供拒絕執行處理器。)可能只是簡單的拒絕任務,也可能會引起execute拋出一個未檢查RejectdExecutionException。一旦所有的任務全部完成後,ExecutorService會轉入終止狀態。你可以調用awaitTermination等待ExecutorService到達終止狀態,也可以輪詢檢查isTerminated判斷ExecutorService是否已經終止。通常shutdown會緊隨awaiTermination之後,這樣可以產生同步地關閉ExetorService的效果。
class LifecycleWebServer{
	private final ExecutorService exec=...;
	
	public void start() throws IOException{
		ServiceSocket socket=new ServerSocket(80);
		while(!exec.isShtudown)){
			try{
				final Socket conn=socket.accept();
				exec.execute(new Runnable(){
					public void run(){handleRequest(conn);}
				};
			}catch(RejectedExecutionException e){
				log("task sunmission rejected",e);
			}
		}
	}
	public void stop(){exec.shutdown();} 
	void handlerRequest(Socket connection){
		Request req=readReuest(connection);
		if(isShutdownRequest(req))
			stop();
		else
			dispatchRequest(req);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章