什么是線程池?為什么要使用線程池?如何使用?

1. 什么是線程池?

線程池其實就是將多個線程對象放到一個容器當中。

2. 為什么使用線程池?

可以重用線程,減少創(chuàng)建和銷毀線程帶來的消耗。

3. 如何使用線程池?

要想知道如何使用線程池,就要先知道線程池的種類有多少種?線程池大概有以下幾種:

  1. ThreadPoolExecutor
  2. FixedThreadPool
  3. CahcedThreadPool
  4. SingleThreadExecutor
  5. ScheduledThreadPool

以下介紹這幾種線程池的用法:

3.1 ThreadPoolExecutor

ThreadPoolExecutor 是線程池真正的實現(xiàn)方法,以下是 ThreadPoolExecutor 的構造方法:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
}

它需要傳入一系列參數(shù)來配置線程池,下面介紹每個參數(shù)的意義。

參數(shù) 意義
corePoolSize 線程池的核心線程數(shù)
maximumPoolSize 線程池容納最大的線程數(shù)
keepAliveTime 非核心線程閑置時的超時時長
unit keepAliveTime 參數(shù)的時間單位
workQueue 線程池中的任務隊列
threadFactory 線程工廠,為線程池提供創(chuàng)建新線程的功能

3.2 FixedThreadPool

一種固定線程數(shù)量的線程池。

可以通過 Executors 的 newFixedThreadPool() 方法創(chuàng)建:

ExecutorService pool = Executors.newFixedThreadPool(4);

newFixedThreadPool() 具體實現(xiàn):

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

可以看出 newFixedThreadPool() 是通過創(chuàng)建 ThreadPoolExecutor 來創(chuàng)建線程池的。

并且因為 corePoolSize 和 maximumPoolSize 是一樣的,所以這種線程池只有核心線程,任務超出線程數(shù)后,會在隊列中等待。

具體使用如下:

ExecutorService pool = Executors.newFixedThreadPool(4);

Runnable task = new Runnable() {
     @Override
      public void run() {
          System.out.println("haha");  
      }
};

pool.execute(task);

3.3 CahcedThreadPool

一種線程數(shù)量不定的線程池。

可以通過 Executors 的 newCachedThreadPool() 方法創(chuàng)建:

ExecutorService pool = Executors.newCachedThreadPool();

newCachedThreadPool() 具體實現(xiàn):

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

可以看到 corePoolSize 為 0,maximumPoolSize 為 Integer.MAX_VALUE,證明這種線程池沒有核心線程,但是有多個非核心線程。

這種線程池的特點就是,當有任務提交時,如果有空閑線程則復用空閑線程,沒有的話就新建線程處理。

空閑線程如果超過 60 秒就會被回收。

具體使用如下:

ExecutorService pool = Executors.newCachedThreadPool();

Runnable task = new Runnable() {
     @Override
      public void run() {
          System.out.println("haha");  
      }
};

pool.execute(task);

3.4 SingleThreadExecutor

一種只有一個工作線程的線程池。

可以通過 Executors 的 newSingleThreadExecutor() 方法創(chuàng)建:

ExecutorService pool = Executors.newSingleThreadExecutor();

newSingleThreadExecutor() 具體實現(xiàn):

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

從源碼可以看出,這種線程池只有一個核心線程,并且總線程數(shù)為 1。

具體使用如下:

ExecutorService pool = Executors.newSingleThreadExecutor();

Runnable task = new Runnable() {
     @Override
      public void run() {
          System.out.println("haha");  
      }
};

pool.execute(task);

3.5 ScheduledThreadPool

一種核心線程數(shù)量固定,非核心線程數(shù)不固定的線程池。

可以通過 Executors 的 newScheduledThreadPool() 方法創(chuàng)建:

ExecutorService pool = Executors.newScheduledThreadPool(4);

newScheduledThreadPool() 具體實現(xiàn):

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

// DEFAULT_KEEPALIVE_MILLIS = 10L
public ScheduledThreadPoolExecutor(int corePoolSize) {
     super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
}

// 進去 super 的代碼
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
      this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
}

從源碼可以看出這種線程池的核心線程是固定的,非核心線程數(shù)沒有限制,但是非核心線程出現(xiàn)空閑后,10 毫秒就會被回收。

具體使用:

ExecutorService pool = Executors.newFixedThreadPool(4);

Runnable task = new Runnable() {
     @Override
      public void run() {
          System.out.println("haha");  
      }
};

// 1 秒后執(zhí)行任務
pool.schedule(task, 1, TimeUnit.SECONDS);

// 延遲 10 毫秒后,每隔 2000 毫秒執(zhí)行一次任務
pool.scheduleAtFixedRate(task, 10,2000, TimeUnit.MICROSECONDS);
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容