線程池的幾個重要的參數:
1、corePoolSize:線程池的核心線程數(也是默認線程數)
2、maximumPoolSize:最大線程數
3、keepAliveTime:允許的線程最大空閑時間(單位/秒)
線程池內部是通過隊列+線程實現的,當我們利用線程池執行任務時:
-
如果此時線程池中的線程數量小于corePoolSize,即使線程池中的線程都處于空閑狀態,也要創建新的線程來處理被添加的任務,
-
如里此時線程池中的線程數量等于corePoolSize,但是緩沖隊列workQueue未滿,那么任務被放入緩沖隊列。
-
如果此時線程池中的線程數量大于等于corePoolSize,緩中隊列workQueue滿,并且線程池中的數量小于maximumPooISize,建新的線程來外理被添加的任務。
-
如果此時線程池中的線程數量大于corePoosize,緩沖隊列workQueue滿,并目線程池中的數量等于maximumPoosize,那么通過 handler所指定的策略來處理此任務。
-
當線程池中的線程數量大于 corePoolsize時,如果某線程空閑時間超過keepAliveTime,線程將被終止。這樣,線程可以動態的調整池中的線程數。
線程池的拒絕策略:指的是RejectedExecutionHandler接口的實現類。
在線程池接口的源代碼中,可以發現ThreadPoolExecutor接口內置了4種拒絕策略。
package java.util.concurrent;public class ThreadPoolExecutor extends AbstractExecutorService {/*** A handler for rejected tasks that runs the rejected task* directly in the calling thread of the {@code execute} method,* unless the executor has been shut down, in which case the task* is discarded.*/public static class CallerRunsPolicy implements RejectedExecutionHandler {/*** Creates a {@code CallerRunsPolicy}.*/public CallerRunsPolicy() { }/*** Executes task r in the caller's thread, unless the executor* has been shut down, in which case the task is discarded.** @param r the runnable task requested to be executed* @param e the executor attempting to execute this task*/public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {if (!e.isShutdown()) {r.run();}}}/*** A handler for rejected tasks that throws a* {@code RejectedExecutionException}.*/public static class AbortPolicy implements RejectedExecutionHandler {/*** Creates an {@code AbortPolicy}.*/public AbortPolicy() { }/*** Always throws RejectedExecutionException.** @param r the runnable task requested to be executed* @param e the executor attempting to execute this task* @throws RejectedExecutionException always*/public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {throw new RejectedExecutionException("Task " + r.toString() +" rejected from " +e.toString());}}/*** A handler for rejected tasks that silently discards the* rejected task.*/public static class DiscardPolicy implements RejectedExecutionHandler {/*** Creates a {@code DiscardPolicy}.*/public DiscardPolicy() { }/*** Does nothing, which has the effect of discarding task r.** @param r the runnable task requested to be executed* @param e the executor attempting to execute this task*/public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {}}/*** A handler for rejected tasks that discards the oldest unhandled* request and then retries {@code execute}, unless the executor* is shut down, in which case the task is discarded.*/public static class DiscardOldestPolicy implements RejectedExecutionHandler {/*** Creates a {@code DiscardOldestPolicy} for the given executor.*/public DiscardOldestPolicy() { }/*** Obtains and ignores the next task that the executor* would otherwise execute, if one is immediately available,* and then retries execution of task r, unless the executor* is shut down, in which case task r is instead discarded.** @param r the runnable task requested to be executed* @param e the executor attempting to execute this task*/public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {if (!e.isShutdown()) {e.getQueue().poll();e.execute(r);}}}}
四種拒絕策略的相關說明:
1、AbortPolicy:
默認。拒絕這個任務,并且拋出RejectedExecutionException異常。
2、DiscardPolicy:
隊列滿了,丟掉任務,不會拋出異常!
3、DiscardOldestPolicy
隊列滿了,嘗試去和最早的競爭,也不會拋出異常!
拋棄最老任務策略,也就是說如果隊列滿了,就會將最早進入隊列的任務拋棄,從隊列中騰出空間,再嘗試加入隊列。因為隊列是隊尾進、隊頭出,隊頭元素是最老的,所以每次都是移除隊頭元素后再嘗試入隊。4、CallerRunsPolicy
調用者執行策略。在新任務被添加到線程池時,如果添加失敗,那么提交任務的線程會自己去執行該任務,不會使用線程池中的線程去執行新任務。