java 線程池

概述

  1. 減小了建立和銷燬線程的次數,每一個工做線程均可以被重複利用,可執行多個任務
  2. 能夠根據系統的承受能力,調整線程池中工做線線程的數目,防止由於由於消耗過多的內存,而把服務器累趴下(每一個線程須要大約1MB內存,線程開的越多,消耗的內存也就越大,最後死機)
  3. 線程池使得線程能夠複用,就是執行完一個任務,並不被銷燬,而是能夠繼續執行其餘的任務,減小建立和銷燬線程的次數。

java 中提供了3種實現

  1. ThreadPoolExecutor:標準線程池
  2. ScheduledThreadPoolExecutor:支持延遲任務的線程池
  3. ForkJoinPool:相似於ThreadPoolExecutor,可是使用work-stealing模式,其會爲線程池中的每一個線程建立一個隊列,從而用work-stealing(任務竊取)算法使得線程能夠從其它線程隊列裏竊取任務來執行。既若是本身的任務處理完成了,則能夠去忙碌的工做線程那裏竊取任務執行。

1.ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler){
 ...... 
}
  • corePoolSize:核心線程池大小,線程池維護的線程最少線程。
  • maximumPoolSize:線程池最大大小。
  • keepAliveTime:線程池中線程的最大空閒時間,若是線程池中的線程個數大於corePoolSize,而且線程空閒時間超過該時間的線程會被回收。
  • unit: 線程池維護線程所容許的空閒時間的單位、可選參數值爲:TimeUnit中的幾個靜態屬性:NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。
  • workQueue: 線程池中存放工做任務的隊列。經常使用的是:java.util.concurrent.ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue
  • threadFactory: 線程工廠,提供建立新線程的功能。ThreadFactory是一個接口,只有一個方法,經過線程工廠能夠對線程的一些屬性進行定製。
  • handler:線程池中的數量大於maximumPoolSize,對拒絕任務的處理策略,默認值ThreadPoolExecutor.AbortPolicy()。

Executors 提供了3個工廠方法建立 ThreadPoolExecutor

  1. newFixedThreadPool 建立一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
}
  1. newCachedThreadPool建立一個可緩存線程池,若是線程池長度超過處理須要,可靈活回收空閒線程,若無可回收,則新建線程。
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
}
  1. newSingleThreadExecutor 建立一個單線程化的線程池,它只會用惟一的工做線程來執行任務,保證全部任務按照指定順序(FIFO, LIFO, 優先級)執行
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
}

2. ScheduledThreadPoolExecutor

咱們經過查看ScheduledThreadPoolExecutor的源代碼,能夠發現ScheduledThreadPoolExecutor繼承了ThreadPoolExecutor。java

public ScheduledThreadPoolExecutor(int corePoolSize,
                                   ThreadFactory threadFactory,
                                   RejectedExecutionHandler handler) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
          new DelayedWorkQueue(), threadFactory, handler);
}

從構造中發現ScheduledThreadPoolExecutor線程池實際上是調用了ThreadPoolExecutor構造進行實現的,只是ThreadPoolExecutor使用的工做隊列是java.util.concurrent.ScheduledThreadPoolExecutor.DelayedWorkQueue經過名字咱們均可以猜到這個是一個延時工做隊列。
由於ScheduledThreadPoolExecutor的最大線程是Integer.MAX_VALUE,並且根據源碼能夠看到execute和submit其實都是調用schedule這個方法,並且延時時間都是指定爲0,因此調用execute和submit的任務都直接被執行。算法

Executors 也提供了ScheduledThreadPoolExecutor建立方式

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

ScheduledThreadPoolExecutor 提供了3種延遲執行策略緩存

  1. schedule(commod,delay,unit) ,這個方法是說系統啓動後,須要等待多久執行,delay是等待時間。只執行一次,沒有周期性。服務器

  2. scheduleAtFixedRate(commod,initialDelay,period,unit),固定速率執行週期任務。這個是以period爲固定週期時間,按照必定頻率來重複執行任務,initialDelay是說系統啓動後,須要等待多久纔開始執行。併發

  3. scheduleWithFixedDelay(commod,initialDelay,delay,unit),固定延遲執行週期任務。這個是以delay爲固定延遲時間,按照必定的等待時間來執行任務,initialDelay意義與上面的相同。函數

3. ForkJoinPool

在Java 7中引入了一種新的線程池:ForkJoinPool。
它同ThreadPoolExecutor同樣,也實現了Executor和ExecutorService接口。它使用了一個無限隊列來保存須要執行的任務,而線程的數量則是經過構造函數傳入,若是沒有向構造函數中傳入但願的線程數量,那麼當前計算機可用的CPU數量會被設置爲線程數量做爲默認值。spa

Executors 提供了 ForkJoinPool 的建立方式

public static ExecutorService newWorkStealingPool() {
    return new ForkJoinPool
        (Runtime.getRuntime().availableProcessors(),
         ForkJoinPool.defaultForkJoinWorkerThreadFactory,
         null, true);
}

併發數默認爲當前系統cpu個數。線程

public static ExecutorService newWorkStealingPool(int parallelism) {
    return new ForkJoinPool
        (parallelism,
        ForkJoinPool.defaultForkJoinWorkerThreadFactory,
        null, true);
}

也能夠指定並行數。code

相關文章
相關標籤/搜索