1. 程式人生 > >Java  手動建立執行緒池

Java  手動建立執行緒池

oracle提供了一個通過ThreadPoolExecutor建立一個執行緒池的類

構造器

使用給定的引數和預設的飽和策略、預設的工廠方法建立執行緒池

ThreadPoolExecutor(int corePoolSize, 
int maximumPoolSize, 
long keepAliveTime, 
TimeUnit unit, 
BlockingQueue<Runnable> workQueue)

使用給定的引數和預設的工廠方法建立執行緒池

ThreadPoolExecutor(int corePoolSize, 
int maximumPoolSize, 
long
keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)

使用給定的引數和預設的飽和策略(AbortPolicy)建立執行緒池

ThreadPoolExecutor(int corePoolSize, 
int maximumPoolSize,
long keepAliveTime,
BlockingQueue<Runnable> workQueue, 
ThreadFactory threadFactory)

使用指定的引數建立執行緒池

ThreadPoolExecutor(int corePoolSize, 
int maximumPoolSize, 
long keepAliveTime, 
TimeUnit unit,
BlockingQueue<Runnable> workQueue, 
RejectedExecutionHandler handler)

引數說明

  • corePoolSize 執行緒池的基本大小, 當提交一個任務到執行緒池的時候,執行緒池會建立一個執行緒來執行任務,即使當前執行緒池已經存在空閒執行緒,仍然會建立一個執行緒,等到需要執行的任務數大於執行緒池基本大小時就不再建立。如果呼叫執行緒池的prestartAllCoreThreads()方法,執行緒池會提前建立並啟動所有的基本執行緒。
  • maximumPoolSizeSize 執行緒池最大數量,執行緒池允許建立的最大執行緒數,如果佇列滿了,並且已建立的執行緒數小於最大執行緒數,則執行緒池會再建立新的執行緒執行任務。值得注意的是,如果使用了無界的任務佇列這個引數就沒什麼效果。
  • keepAliveTime 執行緒活動保持時間,執行緒池的工作執行緒空閒後,保持存活的時間,所以,如果任務很多,並且每個任務執行的時間比較短,可以調大時間,提高執行緒的利用率。
  • unit 執行緒活動保持時間的單位,可選擇的單位有時分秒等等。
  • workQueue 任務佇列。用來暫時儲存任務的工作佇列
  • threadFactory 用於建立執行緒的工廠

佇列

  • ArrayBlockingQueue:是一個基於陣列結構的有界阻塞佇列,此佇列按照FIFO(先進先出)原則對元素進行排序
  • DelayQueue
  • LinkedBlockingDeque
  • LinkedBlockingQueue:是一個基於連結串列結構的有界阻塞佇列,此佇列按照FIFO排序元素,吞吐量高於ArrayBlockingQueue。靜態工廠方法Executors.newFixedThreadPool(n)使用了此佇列
  • LinkedTransferQueue
  • PriorityBlockingQueue:一個具有優先順序的無限阻塞佇列
  • SynchronousQueue:一個不儲存元素的阻塞佇列。每個插入操作必須等待另一個執行緒呼叫移除操作,否則插入操作一直處於阻塞狀態,吞吐量要高於LinkedBlockingQueue,靜態工廠方法Executors.newCachedThreadPool()使用了此佇列

飽和策略

當佇列和執行緒池都滿了,說明執行緒池處於飽和的狀態,那麼必須採取一種策略處理提交的新任務。這個策略預設是AbortPolicy,表示無法處理新任務時丟擲異常

  • ThreadPoolExecutor.AbortPolicy:直接丟擲異常
  • ThreadPoolExecutor.CallerRunsPolicy:只用呼叫這所在的執行緒來執行任務
  • ThreadPoolExecutor.DiscardOldestPolicy:丟棄佇列裡最近的一個任務,並執行當前任務
  • ThreadPoolExecutor.DiscardPolicy:不處理,丟棄掉

示例

public class ThreadPool {

    /**
     * 執行緒池的基本大小
     */
    static int corePoolSize = 10;
    /**
     * 執行緒池最大數量
     */
    static int maximumPoolSizeSize = 100;
    /**
     * 執行緒活動保持時間
     */
    static long keepAliveTime = 1;
    /**
     * 任務佇列
     */
    static ArrayBlockingQueue workQueue = new ArrayBlockingQueue(10);

    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSizeSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                workQueue,
                new ThreadFactoryBuilder().setNameFormat("XX-task-%d").build());
        //提交一個任務
        executor.execute(() -> System.out.println("ok"));
    }
}

參考文件