關於線程池Executor的一些記錄

爲了更好的控制多線程,JDK提供了一套線程框架Executor,幫助開發人員有效的進行線程控制。他們都在,java.util.concurrent包中,是JDK併發包的核心。其中有一個比較重要的類Executor:他扮演着線程工廠的角色,我們通過Executors可以創建具有特定功能的線程池。

Executors創建線程池的方法:

    newCachedThreadPool()方法:返回一個可根據實際使用情況調整線程個數的線程池。不限制最大線程數量,若有空閒的線程則執行任務,若無任務則不創建線程,並且每個空閒線程默認會在60秒後自動回收。

    newFixedThreadPool()方法:返回一個固定數量的線程池,該方法的線程數始終不變。當有一個任務提交時,若線程池中有線程空閒,則立即執行,若沒有空閒線程,則被暫緩在一個任務隊列中等待有空閒的線程去執行。

    newSingleThreadExecutor()方法:創建只有一個線程的線程池。若有空閒線程則立即執行,若沒有,則被暫緩在任務隊列中。

    newScheduledThreadPool()方法:該方法返回一個ScheduledExecutorService對象,具有定時器的功能。

    自定義線程池:若Executors工廠類無法滿足我們的需求,可以自己去常見自定義線程池,其實Executors工廠類中所有的創建線程池方法均是用ThreadPoolExecutor這個類,這個類可以自定義線程,構造方法如下:

  

new ThreadPoolExecutor(int corePoolSize,                                //當前核心線程數(當線程剛new出來時線程池中線程個數)
                               int maximumPoolSize,                                 //最大線程數
                               long keepAliveTime,                                    //保持存活的時間(空閒時間)
                               TimeUnit unit,                                              //空閒時間單位
                               BlockingQueue<Runnable> workQueue    //任務隊列
                               ThreadFactory threadFactory,                     //
                               RejectedExecutionHandler handler             //拒絕執行的任務

                )   

自定義線程池使用詳細:

指定構造方法的隊列是什麼類型的比較關鍵:

    使用有界隊列時,若有新的任務需要執行,如果線程池中實際線程數小於corePoolSize,則優先創建線程;若大於corePoolSize則將該任務加入任務隊列中;若隊列已滿,則在線程總數不大於maxPoolSize的前提下創建新的線程;若線程數大於maxPoolSize則執行拒絕策略,或其他自定義方式。

    使用無界隊列時:LinkedBlockingQueue。與有界隊列相比,除非系統資源耗盡,否則無界的任務隊列不存在任務入隊失敗的問題。當有新任務到來,系統的線程數小於corePoolSize時,則新建線程執行任務;當達到corePoolSize後就不再增加新的線程。若後續還有新任務到來,而又沒有空閒的線程資源,則任務直接進入任務隊列等待。若任務創建與執行的速度差異很大,無界隊列會保持快速增長,直到耗盡系統內存。

    JKD拒絕策略

        AbortPolicy:直接拋出異常系統正常工作

        CallerRunPolicy:只要線程池未關閉,該策略直接在調用者線程中,運行當前被丟棄的任務。

        DiscardOldestPolicy:丟棄最早的一個任務,嘗試再次提交當前任務。

        DiscardPolicy:丟棄無法處理的任務,不給予任何處理。


        其實這四種拒絕策略都比較暴力並不推薦。       

        推薦:如果需要自定義拒絕策略,可以實現RejectedExecutionHandler接口。

關於execute方法和submit方法:

    execute方法:沒有返回值,只是執行線程任務。

    submit方法:會有一個Future的返回值,該類具有get()方法,當get結果爲null時說明該線程執行完畢。

發佈了23 篇原創文章 · 獲贊 13 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章