溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中的線程池有什么用

發布時間:2021-08-20 09:08:26 來源:億速云 閱讀:148 作者:chen 欄目:云計算

這篇文章主要講解了“Java中的線程池有什么用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java中的線程池有什么用”吧!

Java中的線程池

【1】使用線程池的好處:

1)降低資源消耗,通過重復利用已創建的線程降低線程創建和銷毀造成的消耗。
2)提高響應速度,當任務到達時,任務可以不需要等到線程創建就能立即執行。
3)提高線程的可管理性。線程池可以進行統一分配、調優和監控線程。

【2】構造方法:

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler);

參數說明:

	1)corePoolSize:核心池的大小。
	
		1)在創建了線程池后,默認情況下,線程池中并沒有任何線程,而是等待有任務到來才創建線程去執行任務。
		2)默認情況下,在創建了線程池后,線程池中的線程數為0,當有任務來之后,就會創建一個線程去執行任務。
			注意:即使其它空閑的線程能夠執行新任務也會去創建線程,當線程池中的線程數目達到corePoolSize后,就會把到達的任務放到緩存隊列當中。
		3)調用prestartAllCoreThreads()或prestartCoreThread()方法來預創建線程,即在沒有任務到來之前就創建corePoolSize個線程或者一個線程。
		
		
	2)workQueue:任務緩存隊列,是一個阻塞隊列,用來存儲等待執行的任務;類型為BlockingQueue<Runnable>,通??梢匀∠旅?種類型:
	
		1)ArrayBlockingQueue:基于數組的先進先出隊列,此隊列創建時必須指定大??;
		2)LinkedBlockingQueue:基于鏈表的先進先出隊列,如果創建時沒有指定此隊列大小,則默認為Integer.MAX_VALUE,吞吐量通常要高于ArrayBlockingQueue。
			eg:靜態工廠方法Executors.newFixedThreadPool()就是使用的這個隊列。
		3)SynchronousQueue:這個隊列不會保存提交的任務,而是直接新建一個線程來執行新來的任務。
			說明:每個插入操作必須等到另一個線程調用移除操作,否則插入操作一直處于阻塞狀態,吞吐量通常要高于LinkedBlockingQueue。
			eg:靜態工廠方法Executors.newCachedThreadPool使用的就是這個隊列。
		4)PriorityBlockingQueue:一個具有優先級的無限阻塞隊列。
		
		說明:
			1>一般使用LinkedBlockingQueue和SynchronousQueue
			2>建議使用有界隊列,有界隊列能增加系統的穩定性。
				eg:如果線程池里的工作線程全部阻塞,任務積壓在線程池里,如果設置成無界隊列,那么這個隊列會越來越大,有可能會撐滿內存,導致整個系統不可用。

		
	3)maximumPoolSize:線程池中允許創建的最大線程數。
	
		1)如果隊列滿了,并且已創建的線程數小于最大線程數,則線程池會再創建新的線程來執行任務。
		2)如果使用了無界的任務隊列,則這個參數就不起什么作用了(隊列默認的大小是:Integer.MAX_VALUE,在隊列未滿之前,線程池是不會再去創建新線程了)。
	
	
	4)RejectedExecutionHandler:任務拒絕策略,當任務緩存隊列已滿并且線程池中的線程數目達到maximumPoolSize時,如果還有任務到來就會采取任務拒絕策略,通常有以下四種策略:
	
		1)ThreadPoolExecutor.AbortPolicy:		丟棄任務并拋出RejectedExecutionException異常,默認使用該策略。
		2)ThreadPoolExecutor.DiscardPolicy:	丟棄任務,但是不拋出異常;會導致被丟棄的任務無法再次被執行
		3)ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊列最前面的任務,然后重新嘗試執行任務(重復此過程);會導致被丟棄的任務無法再次被執行
		4)ThreadPoolExecutor.CallerRunsPolicy:	由調用線程處理該任務;主線程直接執行該任務,執行完之后嘗試添加下一個任務到線程池中,可以有效降低向線程池內添加任務的速度 

		說明:也可以實現RejectedExecutionHandler接口來自定義策略。


	5)keepAliveTime:表示線程沒有任務執行時最多保持多久時間會終止。
	
		默認情況下,只有當線程池中的線程數大于corePoolSize時,keepAliveTime才會起作用。
		但是如果調用了allowCoreThreadTimeOut(boolean)方法,在線程池中的線程數不大于corePoolSize時,keepAliveTime參數也會起作用,直到線程池中的線程數為0;
		
		
	6)TimeUnit:參數keepAliveTime的時間單位,有7種取值,在TimeUnit類中有7種靜態屬性:
	
		TimeUnit.DAYS;				天
		TimeUnit.HOURS;				小時
		TimeUnit.MINUTES;			分鐘
		TimeUnit.SECONDS;			秒
		TimeUnit.MILLISECONDS;		毫秒
		TimeUnit.MICROSECONDS;		微妙
		TimeUnit.NANOSECONDS;		納秒

		
	7)ThreadFactory:用于設置創建線程的工廠,可以通過線程工廠給每個創建出來的線程設置更有意義的名字。

【3】其它方法:

任務的提交:
	execute(Runnable command):	提交后沒有返回值,故無法判斷任務是否被線程池執行成功。
		
	submit():	提交后返回一個Future對象,通過這個future對象可以判斷任務是否執行成功。
		通過future的get()方法來獲取返回值,該方法會阻塞當前線程直到任務完成。
		get(long timeout, TimeUnit unit)方法:阻塞當前線程一段時間后立即返回,這時候任務可能沒有執行完。



線程池容量的動態調整:
	setCorePoolSize()		設置核心池的大小
	setMaximumPoolSize()	設置線程池最大能創建的線程數

線程池的關閉:

	原理:遍歷線程池中的工作線程,然后逐個調用線程的interrupt方法來中斷線程,所以無法響應中斷的任務可能永遠無法終止。
	
	shutdown()		
		1>將線程池的狀態設置成SHUTDOWN狀態,然后中斷所有沒有正在執行任務的線程。
		2>不再接受新的任務,但是不會立即終止線程池,而是要等所有任務緩存隊列中的任務都執行完后才終止。
	shutdownNow()	
		1>首先將線程池的狀態設置成STOP,然后嘗試停止所有的正在執行或暫停任務的線程,并且清空任務緩存隊列,并返回等待執行任務的列表.

	說明:
		1)只要調用了這兩個關閉方法中的任意一個,isShutdown方法就會返回true。
		2)當所有的任務都已關閉后,才表示線程池關閉成功,這時調用isTerminaed方法會返回true。

【4】線程池的狀態:

// RUNNING狀態:線程池正常運行,可以接受新的任務并處理隊列中的任務
private static final int RUNNING    = -1 << COUNT_BITS;
// SHUTDOWN狀態:不再接受新任務,但是會執行隊列中的任務
private static final int SHUTDOWN   =  0 << COUNT_BITS;
// STOP狀態:不再接受新任務,不處理隊列中的任務,中斷正在處理的任務
private static final int STOP       =  1 << COUNT_BITS;
// 過渡狀態:所有的任務都執行完了,線程池已經沒有有效的線程了,此時線程池的狀態為過渡狀態,并且將要調用terminated()方法
private static final int TIDYING    =  2 << COUNT_BITS;
// 終止狀態:terminated()方法調用完成后的狀態
private static final int TERMINATED =  3 << COUNT_BITS;

1>當線程池剛創建后,線程池處于RUNNING狀態,可以接受新的任務并處理隊列中的任務
2>如果調用了shutdown()方法,則線程池處于SHUTDOWN狀態,此時線程池不能夠接受新的任務,它會等待所有任務執行完畢;
3>如果調用了shutdownNow()方法,則線程池處于STOP狀態,此時線程池不能接受新的任務,并且會去嘗試終止正在執行的任務;
4>當線程池處于SHUTDOWN或STOP狀態,并且所有工作線程已經銷毀,任務緩存隊列已經清空或執行結束后,線程池被設置為TERMINATED狀態。

【5】線程池的處理流程:

ThreadPoolExecutor執行execute方法分下面4種情況。
	1)如果當前運行的線程少于corePoolSize,則創建新線程來執行任務(注意,執行這一步驟需要獲取全局鎖)。
	2)如果運行的線程等于或多于corePoolSize,則將任務加入BlockingQueue。
	3)如果無法將任務加入BlockingQueue(隊列已滿),則創建新的線程來處理任務(注意,執行這一步驟需要獲取全局鎖)。
	4)如果創建新線程將使當前運行的線程超出maximumPoolSize,任務將被拒絕,并調用	RejectedExecutionHandler.rejectedExecution()方法。

感謝各位的閱讀,以上就是“Java中的線程池有什么用”的內容了,經過本文的學習后,相信大家對Java中的線程池有什么用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女