Java線程池七個參數


Java線程池七個參數

首先創建一個定長的線程池

//創建使用固定線程數的線程池
        ExecutorService es2 = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            es2.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "正在執行任務");
                }
            });
        }

點進去看 newFixedThreadPool 的實現

創建線程池的方法實現了 ThreadPoolExecutor 方法。

從源碼中可以看出,線程池的構造函數有7個參數,分別是 corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler

corePoolSize

線程池核心線程大小

線程池中會維護一個最小的線程數量,即使這些線程處理空閑狀態,他們也不會被銷毀,除非設置了allowCoreThreadTimeOut。這里的最小線程數量即是corePoolSize。

maximumPoolSize

線程池最大線程數量

一個任務被提交到線程池以后,首先會找有沒有空閑存活線程,如果有則直接將任務交給這個空閑線程來執行,如果沒有則會緩存到工作隊列(后面會介紹)中,如果工作隊列滿了,才會創建一個新線程,然后從工作隊列的頭部取出一個任務交由新線程來處理,而將剛提交的任務放入工作隊列尾部。線程池不會無限制的去創建新線程,它會有一個最大線程數量的限制,這個數量即由maximunPoolSize指定。

keepAliveTime

空閑線程存活時間

一個線程如果處於空閑狀態,並且當前的線程數量大於corePoolSize,那么在指定時間后,這個空閑線程會被銷毀,這里的指定時間由keepAliveTime來設定

unit

keepAliveTime的計量單位

TimeUnit.DAYS;               //天
TimeUnit.HOURS;             //小時
TimeUnit.MINUTES;           //分鍾
TimeUnit.SECONDS;           //秒
TimeUnit.MILLISECONDS;      //毫秒
TimeUnit.MICROSECONDS;      //微妙
TimeUnit.NANOSECONDS;       //納秒

workQueue

工作隊列

新任務被提交后,會先進入到此工作隊列中,任務調度時再從隊列中取出任務。jdk中提供了四種工作隊列:

  • ArrayBlockingQueue 有界隊列

基於數組的有界阻塞隊列,按FIFO排序。新任務進來后,會放到該隊列的隊尾,有界的數組可以防止資源耗盡問題。當線程池中線程數量達到corePoolSize后,再有新任務進來,則會將任務放入該隊列的隊尾,等待被調度。如果隊列已經是滿的,則創建一個新線程,如果線程數量已經達到maxPoolSize,則會執行拒絕策略。

  • LinkedBlockingQuene 無界隊列

基於鏈表的無界阻塞隊列(其實最大容量為Interger.MAX),按照FIFO排序。由於該隊列的近似無界性,當線程池中線程數量達到corePoolSize后,再有新任務進來,會一直存入該隊列,而不會去創建新線程直到maxPoolSize,因此使用該工作隊列時,參數maxPoolSize其實是不起作用的。

  • SynchronousQuene 直接提交

一個不緩存任務的阻塞隊列,生產者放入一個任務必須等到消費者取出這個任務。也就是說新任務進來時,不會緩存,而是直接被調度執行該任務,如果沒有可用線程,則創建新線程,如果線程數量達到maxPoolSize,則執行拒絕策略。

  • PriorityBlockingQueue 優先級隊列

具有優先級的無界阻塞隊列,優先級通過參數Comparator實現。

ArrayBlockingQueue和PriorityBlockingQueue使用較少,一般使用LinkedBlockingQueue和SynchronousQueue。

線程池的排隊策略與BlockingQueue有關 (可查看線程池 newScheduledThreadPool 的創建方式)。

threadFactory

用於設置創建線程的工廠,可以通過線程工廠給每個創建出來的線程做些更有意義的事情,比如 設定線程名、設置daemon和優先級等等

handler

拒絕策略

當工作隊列中的任務已到達最大限制,並且線程池中的線程數量也達到最大限制,這時如果有新任務提交進來,該如何處理呢。這里的拒絕策略,就是解決這個問題的,jdk中提供了4中拒絕策略:

  • CallerRunsPolicy 只用調用者所在線程來運行任務

該策略下,在調用者線程中直接執行被拒絕任務的run方法,除非線程池已經shutdown,則直接拋棄任務。

  • AbortPolicy 直接拋出異常

該策略下,直接丟棄任務,並拋出RejectedExecutionException異常。

  • DiscardPolicy 不處理,丟棄掉

該策略下,直接丟棄任務,什么都不做。

  • DiscardOldestPolicy 丟棄隊列里最近的一個任務,並執行當前任務

該策略下,拋棄進入隊列最早的那個任務,然后嘗試把這次拒絕的任務放入隊列

  • 也可以根據應用場景需要來實現RejectedExecutionHandler接口自定義策略。如記錄日志或持久化不能處理的任務。


免責聲明!

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



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