【多線程 5】線程池的類型以及submit()和execute()的區別


就跟題目說的一樣,本篇博客,本寶寶主要介紹兩個方面的內容,其一:線程池的類型及其應用場景;其二:submit和execute的區別。那么需要再次重申的是,對於概念性的東西,我一般都是從網上挑選截取,再結合自己的想法進行說明。

一、線程池概述

首先,線程池的使用,是非必須的。並不是涉及到啟用多線程的地方,就非得整出個線程池出來!

1.1,什么是線程池

線程池是一種多線程處理形式,處理過程中將任務添加到隊列,然后在創建線程后自動啟動這些任務。線程池線程都是后台線程。

1.2,為什么用

備注:個人瞎扯,讀者自行評估可信度

線程池——池——容器;那么線程池里面裝着啥呢,線程!

知道為什么盛水的容器,有杯子、有瓶子、有桶、有河......不?

所以,不要拿一個線程池去裝一、兩個線程。線程池,也是一種資源的消耗,它主要解決的是線程的生命周期和資源開銷問題!比如說,我們常用的方式是,在需要一個線程的時候,去創建一個線程,然后用完了之后,再進行銷毀。如果一個程序段需要啟用10個線程,那么我們就將執行10次這樣的操作和切換。這個過程中,資源的消耗和時間的消耗是需要考慮的。那么,使用線程池是什么呢?

1,在需要用到多線程的時候,先創建一個線程池,另其睡眠,再要使用的時候,直接喚醒拿過來用,然后用完了,進行統一銷毀!

2,作為容器,那么必定有容量的概念。線程池能控制最大的工作線程數量,保證資源的有效利用!


1.3,線程池的結構

1、線程池管理器(ThreadPoolManager):用於創建並管理線程池
2、工作線程(WorkThread): 線程池中線程
3、任務接口(Task):每個任務必須實現的接口,以供工作線程調度任務的執行。
4、任務隊列:用於存放沒有處理的任務。提供一種緩沖機制。


1.4,怎么用

首先看看線程池的類圖:


雖然executor是線程池的頂層接口,但真正實現的接口卻是:executorService,所以,當我們使用線程池的時候,用如下代碼:

<span style="font-family:KaiTi_GB2312;font-size:18px;">ExecutorService threadPool = Executors.newSingleThreadExecutor();</span>


備注:newSingleThreadExecutor()是線程池的其中一種類型!可以根據需要,實例化其他類型!

二、線程池的類型及其應用場景

2.1,newFixedThreadPool

創建一個指定工作線程數量的線程池。每當提交一個任務就創建一個工作線程,如果工作線程數量達到線程池初始的最大數,則將提交的任務存入到池隊列中。

2.2,newCachedThreadPool

創建一個可緩存的線程池。這種類型的線程池特點是: 
1).工作線程的創建數量幾乎沒有限制(其實也有限制的,數目為Interger. MAX_VALUE), 這樣可靈活的往線程池中添加線程。 
2).如果長時間沒有往線程池中提交任務,即如果工作線程空閑了指定的時間(默認為1分鍾),則該工作線程將自動終止。終止后,如果你又提交了新的任務,則線程池重新創建一個工作線程。

2.3,newSingleThreadExecutor

創建一個單線程化的Executor,即只創建唯一的工作者線程來執行任務,如果這個線程異常結束,會有另一個取代它,保證順序執行。單工作線程最大的特點是可保證順序地執行各個任務,並且在任意給定的時間不會有多個線程是活動的 。

 

PS:至始至終都只有一個線程,那用線程池干嘛呢?直接創建一個新的線程不就可以了嘛,不懂!

2.4,newScheduleThreadPool

創建一個定長的線程池,而且支持定時的以及周期性的任務執行,類似於Timer。

2.5,幾種類型的對比

FixedThreadPool
是一個典型且優秀的線程池,它具有線程池提高程序效率和節省創建線程時所耗的開銷的優點。但是,在線程池空閑時,即線程池中沒有可運行任務時,它不會釋放工作線程,還會占用一定的系統資源。
CachedThreadPool
特點是在線程池空閑時,即線程池中沒有可運行任務時,它會釋放工作線程,從而釋放工作線程所占用的資源。但是,但當出現新任務時,又要創建一新的工作線程,又要一定的系統開銷。並且,在使用CachedThreadPool時,一定要注意控制任務的數量,否則,由於大量線程同時運行,很有會造成系統癱瘓。

 


三、submit()和execute()的區別

JDK5往后,任務分兩類:一類是實現了Runnable接口的類,一類是實現了Callable接口的類。兩者都可以被ExecutorService執行,它們的區別是:

execute(Runnable x) 沒有返回值。可以執行任務,但無法判斷任務是否成功完成。——實現Runnable接口
submit(Runnable x) 返回一個future。可以用這個future來判斷任務是否成功完成。——實現Callable接口


四、總結

線程池的基本概念就介紹到這里了,接下來會再看看線程的監聽以及任務調度的問題!不過功力不很夠,估計得先自己瞅點書然后寫寫代碼,想想項目中如何運用才能發博客了!這段時間都要被高數整崩潰了,要不是有周軍周大哥的《數學之美》支撐着我,早就跨下了,加油吧!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM