java中常見的四種執行緒池的區別

南小瓜發表於2018-12-18

在使用執行緒時,可以這樣建立一個執行緒池:

ExecutorService executorService= Executors.newCachedThreadPool();
executorService.execute(()-> System.out.println("run ..."));

檢視下java.util.concurrent.Executors原始碼,可以發現有四種建立執行緒池的方法,分別為:newCacbedThreadPool、newFixedThreadPool、newScheduledThreadPool、newSingleThreadExecutor,其實這四種建立執行緒池的方法都是有ThreadPoolExecutor來實現的。原始碼結構圖如下:

下面來分別看一下這四種執行緒池:

一、newCacheThreadPool

為每一個任務建立一個執行緒,並且也可以重用已有的執行緒,無核心執行緒數量,超過60s的空閒執行緒將棄用,但是會受到系統實際記憶體的執行緒。原始碼如下:

 /**無參構造方法*/
 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
 /**有參的構造方法,可以傳入threadFactory*/
 public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>(),
                                      threadFactory);
    }

二、newFixedThreadPool

核心執行緒數和最大執行緒數是相同的,並且無空閒執行緒,核心執行緒數無限時要求,就是可以建立固定大小的執行緒數量,同時阻塞佇列是沒有大小限制的,原始碼如下:

/**建立固定大小的執行緒數*/
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

/**建立固定大小的執行緒數,並可以指定threadFactory*/
 public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>(),
                                      threadFactory);
    }

三、newScheduledThreadPool

具有延遲和週期執行執行緒的執行緒池,固定的核心執行緒數,最大執行緒數沒有限制,空閒的執行緒會立即啟用原始碼如下:

/**建立固定大小的corePool*/
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
/**檢視ScheduledThreadPoolExecutor類,發現是整合的ThreadPoolExecutor*/
 public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }
/**建立固定大小的corePool,並指定threadFactory*/
 public static ScheduledExecutorService newScheduledThreadPool(
            int corePoolSize, ThreadFactory threadFactory) {
        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
    }
/**檢視ScheduledThreadPoolExecutor類,發現是整合的ThreadPoolExecutor*/
 public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue(), threadFactory);
    }

四、newSingleThreadExecutor

建立只有一個的核心執行緒,只處理一個執行緒,其實並不能處理併發,原始碼如下:

/**無參*/
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}
/**指定threadFactory*/
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1, threadFactory));
    }

以上四種建立執行緒池的方式,通過原始碼可以發現都是基於ThreadPoolExecutor類中的構造方法進行實現的。

相關文章