/** * Creates a new {@code ThreadPoolExecutor} with the given initial * parameters. * * @param corePoolSize the number of threads to keep in the pool, even * if they are idle, unless {@code allowCoreThreadTimeOut} is set * @param maximumPoolSize the maximum number of threads to allow in the * pool * @param keepAliveTime when the number of threads is greater than * the core, this is the maximum time that excess idle threads * will wait for new tasks before terminating. * @param unit the time unit for the {@code keepAliveTime} argument * @param workQueue the queue to use for holding tasks before they are * executed. This queue will hold only the {@code Runnable} * tasks submitted by the {@code execute} method. * @param threadFactory the factory to use when the executor * creates a new thread * @param handler the handler to use when execution is blocked * because the thread bounds and queue capacities are reached * @throws IllegalArgumentException if one of the following holds:<br> * {@code corePoolSize < 0}<br> * {@code keepAliveTime < 0}<br> * {@code maximumPoolSize <= 0}<br> * {@code maximumPoolSize < corePoolSize} * @throws NullPointerException if {@code workQueue} * or {@code threadFactory} or {@code handler} is null */ public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
一、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
該策略下,拋棄進入隊列最早的那個任務,然后嘗試把這次拒絕的任務放入隊列
