併發編程系列之線程池工廠類:Executors

前言

上節講了講自定義線程池,今天我們來聊聊線程池框架,在實際開發中我們還是基本使用線程框架Executor給我們提供的一些工具類,Java提供的Executor都在JUC(java.util.concurrent)包下面,主要包括:線程池工廠類Executors,線程池實現類ThreadPoolExecutor等,今天呢我們主要聊聊Executors,看看通過Executors我們可以做什麼?OK,不多說廢話,我們馬上進入今天的主題,讓我們揚帆起航,開啓今天的併發之旅吧。

 

什麼是Executors?

Executors,扮演的是線程工廠的角色,一定要與Executor相區分開,Executors只是Executor框架中的一個工廠類而已,通過Executors我們可以創建特定功能的線程池(ThreadPoolExecutor),通過這句話你是不是對Executors和ThreadPoolExecutor的關係有了一定的認識,這兩個都是Executor框架中的一部分(關於Executor框架的各個成員組成這裏就先不做說明,今天主要是學會怎麼使用線程工廠創建線程池)。

 

如何使用Executors?

線程池ThreadPoolExecutor通常都是通過Executors來創建的,我們可以根據自己的需求創建下面幾種不同作用的線程池:

// 創建一個固定數量的線程池
ExecutorService ExecutorService1 = Executors.newFixedThreadPool(10);
// 返回一個可根據實際情況調整線程個數的線程池
ExecutorService ExecutorService2 = Executors.newCachedThreadPool();
// 創建一個線程數量爲1的線程池
ExecutorService ExecutorService3 = Executors.newSingleThreadExecutor();
// 返回一個ScheduledExecutorService對象,該對象也是調用父類的線程池方法,類似newFixedThreadPool
ScheduledExecutorService ScheduledExecutorService = Executors.newScheduledThreadPool(5);

線程池的使用之前講自定義線程池已經說過了,主要也就是:

  • execute向線程池提交任務

  • shutdown和shutdownNow關閉線程池

 

newFixedThreadPool:該方法返回一個固定數量的線程池,該方法的線程數量始終不變,當有任務提交時,若線程池中有空閒線程,則立即執行,若沒有,則會被緩存在一個任務隊列中等待有空閒的線程再去執行;(核心線程數等於最大線程數,默認空閒時間爲0,空閒立馬銷燬),該方法有2個實現,我們看下面源碼:

public static ExecutorService newFixedThreadPool(int nThreads) {
       return new ThreadPoolExecutor(nThreads, nThreads,
                                     0L, TimeUnit.MILLISECONDS,
                                     new LinkedBlockingQueue<Runnable>());
   }

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
       return new ThreadPoolExecutor(nThreads, nThreads,
                                     0L, TimeUnit.MILLISECONDS,
                                     new LinkedBlockingQueue<Runnable>(),
                                     threadFactory);
   }

再分別看下這2個方法在線程池中的實現:

// 我們會發現沒有傳入線程工廠的方法調用了一個默認的線程工廠
public ThreadPoolExecutor(int corePoolSize,
                             int maximumPoolSize,
                             long keepAliveTime,
                             TimeUnit unit,
                             BlockingQueue<Runnable> workQueue) {
       this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
            Executors.defaultThreadFactory(), defaultHandler);
   }

// 而有傳入線程工廠的方法調用自己傳入的線程工廠
public ThreadPoolExecutor(int corePoolSize,
                             int maximumPoolSize,
                             long keepAliveTime,
                             TimeUnit unit,
                             BlockingQueue<Runnable> workQueue,
                             ThreadFactory threadFactory) {
       this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
            threadFactory, defaultHandler);
   }

 

newSingleThreadExecutor:創建一個線程數量爲1的線程池,若空閒則執行,否則入隊列等待被執行;(核心線程數量爲1,最大線程數量也爲1,空閒等待時間爲0),該方法也有2個實現,一個帶自定義的線程工廠,一個不帶:

public static ExecutorService newSingleThreadExecutor() {
       return new FinalizableDelegatedExecutorService
           (new ThreadPoolExecutor(1, 1,
                                   0L, TimeUnit.MILLISECONDS,
                                   new LinkedBlockingQueue<Runnable>()));
   }

public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
       return new FinalizableDelegatedExecutorService
           (new ThreadPoolExecutor(1, 1,
                                   0L, TimeUnit.MILLISECONDS,
                                   new LinkedBlockingQueue<Runnable>(),
                                   threadFactory));
   }

 

newCachedThreadPool:返回一個可根據實際情況調整線程個數的線程池,不限制最大線程數量,若有任務則沒線程時則創建線程,每個線程空閒等待時間爲60秒,60秒後如果該線程沒有任務可執行,則被回收;(核心線程數量爲0,最大線程數量爲最大,空閒等待時間爲60s)

public static ExecutorService newCachedThreadPool() {
       return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                     60L, TimeUnit.SECONDS,
                                     new SynchronousQueue<Runnable>());
   }

  public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
       return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                     60L, TimeUnit.SECONDS,
                                     new SynchronousQueue<Runnable>(),
                                     threadFactory);
   }

本文由“壹伴編輯器”提供技術支持

newScheduledThreadPool:返回一個ScheduledExecutorService對象,該線程池可以指定線程數量

// 返回一個ScheduledExecutorService對象
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
       return new ScheduledThreadPoolExecutor(corePoolSize);
   }

// 調了父類super的方法裏面還是一個ThreadPoolExecutor
public ScheduledThreadPoolExecutor(int corePoolSize) {
       super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
             new DelayedWorkQueue());
   }
// 父類super中的ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
                             int maximumPoolSize,
                             long keepAliveTime,
                             TimeUnit unit,
                             BlockingQueue<Runnable> workQueue) {
       this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
            Executors.defaultThreadFactory(), defaultHandler);
   }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章