java ThreadPoolExecutor 自定義線程池優勢

java併發線程池建議還是多多使用ThreadPoolExecutor的構造函數來設置自定義的線程池,先來看看這個構造函數的參數列表。

    /**
     * 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) {

通過這些參數列表我們就可以實現一個自定義的線程池了。
1)線程池中核心線程數,
2)線程池中最大線程數,
3)線程池中線程的最大空閒時間,超過這個時間空閒線程將被回收。
4)阻塞隊列的定義,你可以設置是ArrayList還是LinkedList的阻塞隊列,
5)線程工廠,還可以使用自定義的線程工廠,使線程池中的線程打上你自己獨有的標籤,方便調試。自定義線程工廠很簡單,只需要繼承ThreadFactory然後重寫newThread方法即可。
6)線程拒絕策略,典型的幾類線程池默認策略都是拋出異常,其實你可以自定義線程拒絕策略,目前ThreadPoolExecutor爲我們提供了4種策略,分別是:
A:ThreadPoolExecutor.AbortPolicy 直接拋出異常
B:ThreadPoolExecutor.DiscardPolicy 丟棄當前被拒絕的任務(而不拋出任何異常)
C:ThreadPoolExecutor.DiscardOldestPolicy 將緩衝區中最老的任務丟棄,然後重新嘗試接納被拒絕的任務
D:ThreadPoolExecutor.CallerRunsPolicy 在任務的提交方線程中運行被拒絕的任務
不滿足的話,自己還可以實現自定義的線程拒絕策略,實現方法也很簡單,只需要實現RejectedExecutionHandler接口中定義的方法即可。

利用上面提到的6個參數就可以實現一個自定義的線程池了。
這裏再說明一下什麼時候會觸發拒絕線程提交的handler,
1)池中線程數小於corePoolSize時,新任務都不排隊而是直接添加新線程。
2)池中線程數大於等於corePoolSize時,workQueue未滿,首選將新任務加入workQueue而不是添加新線程。
3)池中線程數大於等於corePoolSize時,workQueue已滿,但是線程數小於maximumPoolSize,添加新的線程來處理被添加的任務。
4)池中線程數大於等於corePoolSize,workQueue已滿,並且線程數大於等於maximumPoolSize時,新任務被拒絕,使用handler處理被拒絕的任務。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章