每次建立和關閉線程都會須要花費時間(會引發系統上下文的切換),若是爲每個任務都建立一個線程,就可能會出現建立和關閉的時間大於單線程運行的時間,失去多線程的優點。算法
爲了不頻繁的建立和銷燬線程,咱們能夠將建立的線程進行復用,使用線程池去維護必定活躍的線程,在須要使用到線程的時候,直接從線程池中取,無需從新建立,使用完也無需關閉線程,直接將其歸還至線程池中,減小這部分的性能消耗。多線程
2.Executor框架提供如下五種建立線程池的靜態工廠方法框架
corePoolSize:指定了線程池中線程的數量。函數
maximumPoolSize:指定了線程池中最大的線程數。性能
keepAliveTime:當線程數超過corePoolSize時,多餘空閒線程的存活時間。即,超過corePoolSize的空閒線程,會在多長時間內,會被銷燬。線程
unit:KeepAliveTime的時間單位,使用TimeUnit類。3d
workQueue:任務隊列,被提交但還沒有被執行的任務。cdn
threadFactory:線程工廠,用於建立線程,通常使用默認便可。對象
handler:拒絕策略,當任務太多來不及處理,如何拒絕任務。blog
SynchronousQueue(直接提交的隊列,newCachedThreadPool使用該隊列),他是一個特殊的BlockingQueue,它沒有容量,每個插入操做都須要等待一個相應的刪除操做,反之,每個刪除操做都須要等待一個插入的操做,提交的任務不會真正的保存,而老是將新任務提交給線程執行,若是沒有空閒的進程,則嘗試建立新的進程,若是進程數量已經達到最大值,則執行拒絕策略。所以,使用SynchronousQueue隊列,一般要設置很大的maximumPoolSize值,不然很容易執行拒絕策略。
ArrayBlockingQueue(有界的任務隊列),ArayBlockingQueue 的構造函數必須帶一個容量參數,表示該隊列的最大容量,以下所示當使用有界的任務隊列時,如有新的任務須要執行,若是線程池的實際線程數小於corePoolSize,則會優先建立新的線程,若大於corePoolSize,則會將新任務加入等待隊列。若等待隊列已滿,沒法加入,則在總線程數不大於maximumPoolSize的前提下,建立新的進程執行任務。若大於maximumPoolSize,則執行拒絕策略。可見,有界隊列僅當在任務隊列裝滿時,纔可能將線程數提高到corePoolSize以上,換言之,除非系統很是繁忙,不然確保核心線程數維持在在corePoolSize。
LinkedBlockingQueue(無界的任務隊列,newFixedThreadPool和newSingleThreadExecutor使用該隊列),與有界隊列相 比,除非系統資源耗盡,不然無界的任務隊列不存在任務入隊失敗的狀況。當有新的任務到來,系統的線程數小於corePoolSize時,線程池會生成新的線程執行任務,但當系統的線程數達到corePoolSize後,就不會繼續增長。若後續仍有新的任務加入,而又沒有空閒的線程資源,則任務直接進入隊列等待。若任務建立和處理的速度差別很大,無界隊列會保持快速增加,直到耗盡系統內存。
PriorityBlockingQueue(優先任務隊列是帶有執行優先級的隊列),能夠控制任務的執行前後順序,它是一個特殊的無界隊列。不管是有界隊列ArrayBlockingQueue,仍是未指定大小的無界隊列LinkedBlockingQueue 都是按照先進先出算法處理任務的。而PriorityBlockingQueue則能夠根據任務自身的優先級順序前後執行,在確保系統性能的同時,也能有很好的質量保證(老是確保高優先級的任務先執行)。