建立線程池的四種方式
- CachedThreadPool建立一個可緩存線程池,若是線程池長度超過處理須要,可靈活回收空閒線程,若無可回收,則新建線程。
- FixedThreadPool 建立一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。
- ScheduledThreadPool 建立一個定長線程池,支持定時及週期性任務執行。
- SingleThreadExecutor 建立一個單線程化的線程池,它只會用惟一的工做線程來執行任務,保證全部任務按照指定順序(FIFO, LIFO, 優先級)執行。
建立線程池的七個參數
![image image](http://static.javashuo.com/static/loading.gif)
從源碼中能夠看出,線程池的構造函數有7個參數,分別是corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。下面會對這7個參數一一解釋。數組
- corePoolSize 線程池核心線程大小
線程池中會維護一個最小的線程數量,即便這些線程處理空閒狀態,他們也不會 被銷燬,除非設置了allowCoreThreadTimeOut。這裏的最小線程數量便是corePoolSize。
- maximumPoolSize 線程池最大線程數量
一個任務被提交到線程池後,首先會緩存到工做隊列(後面會介紹)中,若是工做隊列滿了,則會建立一個新線程,而後從工做隊列中的取出一個任務交由新線程來處理,而將剛提交的任務放入工做隊列。線程池不會無限制的去建立新線程,它會有一個最大線程數量的限制,這個數量即由maximunPoolSize來指定。
- keepAliveTime 空閒線程存活時間
一個線程若是處於空閒狀態,而且當前的線程數量大於corePoolSize,那麼在指定時間後,這個空閒線程會被銷燬,這裏的指定時間由keepAliveTime來設定
- unit 空間線程存活時間單位
keepAliveTime的計量單位
- workQueue 工做隊列
新任務被提交後,會先進入到此工做隊列中,任務調度時再從隊列中取出任務。jdk中提供了四種工做隊列:①ArrayBlockingQueue
基於數組的有界阻塞隊列,按FIFO排序。新任務進來後,會放到該隊列的隊尾,有界的數組能夠防止資源耗盡問題。當線程池中線程數量達到corePoolSize後,再有新任務進來,則會將任務放入該隊列的隊尾,等待被調度。若是隊列已是滿的,則建立一個新線程,若是線程數量已經達到maxPoolSize,則會執行拒絕策略。
②LinkedBlockingQuene
基於鏈表的無界阻塞隊列(其實最大容量爲Interger.MAX),按照FIFO排序。因爲該隊列的近似無界性,當線程池中線程數量達到corePoolSize後,再有新任務進來,會一直存入該隊列,而不會去建立新線程直到maxPoolSize,所以使用該工做隊列時,參數maxPoolSize實際上是不起做用的。
③SynchronousQuene
一個不緩存任務的阻塞隊列,生產者放入一個任務必須等到消費者取出這個任務。也就是說新任務進來時,不會緩存,而是直接被調度執行該任務,若是沒有可用線程,則建立新線程,若是線程數量達到maxPoolSize,則執行拒絕策略。
④PriorityBlockingQueue
具備優先級的無界阻塞隊列,優先級經過參數Comparator實現。緩存
- threadFactory 線程工廠
建立一個新線程時使用的工廠,能夠用來設定線程名、是否爲daemon線程等等
-
handler 拒絕策略
當工做隊列中的任務已到達最大限制,而且線程池中的線程數量也達到最大限制,這時若是有新任務提交進來,該如何處理呢。這裏的拒絕策略,就是解決這個問題的,jdk中提供了4中拒絕策略:併發
- ①CallerRunsPolicy 該策略下,在調用者線程中直接執行被拒絕任務的run方法,除非線程池已經shutdown,則直接拋棄任務。
- ②AbortPolicy 該策略下,直接丟棄任務,並拋出RejectedExecutionException異常。
- ③DiscardPolicy 該策略下,直接丟棄任務,什麼都不作。
- ④DiscardOldestPolicy 該策略下,拋棄進入隊列最先的那個任務,而後嘗試把此次拒絕的任務放入隊列