ThreadPoolExecutor的創建


  • 當我們需要創建線程池時,我們可以使用Executors工具類創建相應的如FixedThreadPoolSingleThreadPoolCachedThreadPool等線程池。

  • 注意實際上並不是存在FixedThreadPoolSingleThreadPoolCachedThreadPool這三個類,只是Executors通過調用ThreadPoolExecutor的構造方法傳入不同的參數,從而創建了不同的ThreadPoolExecutor

  • 但是很多公司規范如阿里巴巴編碼規范規定不能使用Executors工具類來創建線程池,因為其創建的線程池要么沒有限制任務的最大值,要么沒有限制工作線程的最大值,會導致OOM異常。

  • 有時候如果我們沒有設置executor.allowCoreThreadTimeOut(true)或者沒有執行executor.shutdown();,使用線程池的進程總是沒有退出,這是因為核心線程的狀態是WAITING (parking),而只有當JVM中只存在守護線程的時候,JVM才會徹底退出。如下圖(圖源極客時間)所示,如果想要一個線程終止,唯一的途徑是讓其從RUNNABLE狀態轉換為TERMINATED。那么如何讓線程從WAITING狀態轉換為RUNNABLE呢?可以使用中斷來終止線程,executorshutdown方法正是調用了interruptIdleWorkers方法來一一中斷工作線程,使用二階段終止模式優雅地終止工作線程的。

  • 所以我們可以自己封裝一個ThreadPoolExecutorBuilder來創建ThreadPoolExecutor,封裝如下,可以創建一個有界的默認參數線程池,也可以方便地自定義參數:

public class ThreadPoolExecutorBuilder {
    private int corePoolSize;
    private int maximumPoolSize;
    private long keepAliveTime;
    private TimeUnit unit;
    private BlockingQueue<Runnable> workQueue;
    private RejectedExecutionHandler handler;
    private ThreadFactory threadFactory;
    private static AtomicInteger threadId = new AtomicInteger();

    /**
     * 默認構造方法設置默認參數
     */
    public ThreadPoolExecutorBuilder() {
        int processors = Runtime.getRuntime().availableProcessors();
        // 核心工作線程以及最大空閑線程數目
        this.corePoolSize = processors;
        this.maximumPoolSize = 2 * processors;
        // 空閑線程的最大存活時間(注意參數生效的條件)
        // 當線程池中線程數量大於corePoolSize(核心線程數量)或設置了allowCoreThreadTimeOut(是否允許空閑核心線程超時)時,線程會根據keepAliveTime的值進行活性檢查,一旦超時便銷毀線程
        this.keepAliveTime = 8;
        this.unit = TimeUnit.SECONDS;
        // 任務隊列以及飽和處理策略
        this.workQueue = new ArrayBlockingQueue<>(16);
        this.handler = new ThreadPoolExecutor.AbortPolicy();
        // 創建線程的工廠,一般可以用來對線程命名
        this.threadFactory = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, "threadPoolWorker-" + threadId.getAndIncrement());
            }
        };
    }

    public ThreadPoolExecutor build() {
        return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    public ThreadPoolExecutorBuilder setCapacity(int corePoolSize, int maximumPoolSize) {
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        return this;
    }

    public ThreadPoolExecutorBuilder setKeepAliveTime(long keepAliveTime, TimeUnit unit) {
        this.keepAliveTime = keepAliveTime;
        this.unit = unit;
        return this;
    }

    public ThreadPoolExecutorBuilder setWorkQueueAndRejectHandler(BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        this.workQueue = workQueue;
        this.handler = handler;
        return this;
    }

    public ThreadPoolExecutorBuilder setThreadFactory(ThreadFactory threadFactory) {
        this.threadFactory = threadFactory;
        return this;
    }
}


免責聲明!

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



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