多執行緒程式設計基礎(二)-- 執行緒池的使用

ClericYi發表於2020-02-21

多執行緒程式設計基礎(二)-- 執行緒池的使用

前言

多執行緒程式設計基礎(一)中,講到了執行緒最基本的使用方法。但是在阿里的開發規範上,這是不值得推薦的。可以在idea中下一個Alibaba Java Coding Guidelines,來糾正我們開發時的習慣。

外掛的使用效果

思考

  1. 如何使用多執行緒?
  2. 如此使用多執行緒開發的好處是什麼?

執行緒池

就上面的第一個問題,我們引入的是一個執行緒池的概念。想來之前在享元模式中,我們就提及過緩衝池的概念,那麼執行緒池是什麼樣的呢?

執行緒池執行模型

從圖中我們可以獲得資訊有

  1. 任務佇列:workQueue
  2. 核心執行緒數:coolPoolSize
  3. 最大執行緒數:maximumPoolSize
  4. 飽和策略:RejectedExecutionHandler

當然,其實需要的引數還有很多。

// ThreadPoolExecutor的建構函式
ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)
複製程式碼

執行緒池分為很多種類,最常用的是這四種:FixedThreadPool、CachedThreadPool、SingleThreadExecutor、ScheduledThreadPool。

FixedThreadPool

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

從填入的函式可以看出最大執行緒數和核心執行緒數的數量相同,也就意味著只有核心執行緒了,多出的任務,將會被放置到LinkedBlockingQueue中。

CachedThreadPool

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

沒有核心執行緒,最大執行緒數為無窮,也就意味著全部都是非核心執行緒。這樣的執行緒池更適合去完成大量需要立即處理,但是耗時短的任務。

SingleThreadExecutor

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

核心執行緒數和最大執行緒數相同,且都為1,也就意味著任務是按序工作的。

ScheduledThreadPool

public static ScheduledExecutorService newScheduledThreadPool(
            int corePoolSize, ThreadFactory threadFactory) {
        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}

public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue(), threadFactory);
}
複製程式碼

從函式名就已經說明了,是一種定時任務。其實就我的思考,他可以用於實現各種各樣功能類似的其他執行緒池。因為DelayedWorkQueue佇列中你可以插入一個立刻需要執行的任務。

使用執行緒池的好處

  • 執行緒的複用

每次使用執行緒我們是不是需要去建立一個Thread,然後start(),然後就等結果,最後的銷燬就等著垃圾回收機制來了。 但是問題是如果有1000個任務呢,你要建立1000個Thread嗎?如果建立了,那回收又要花多久的時間?

  • 控制執行緒的併發數

存在核心執行緒和非核心執行緒,還有任務佇列,那麼就可以保證資源的爭奪是處於一個儘量可控的狀態的。

  • 執行緒的管理

以上就是我的學習成果,如果有什麼我沒有思考到的地方或是文章記憶體在錯誤,歡迎與我分享。


相關文章推薦:

多執行緒程式設計基礎(一)-- 執行緒的使用

JVM必備基礎知識(一) -- 類的載入機制

聊一聊設計模式(一)-- 六大原則

相關文章