Java多線程六

1 線程池的實現原理及基本類結構

  合理利用線程池能夠帶來三個好處。

  1. 降低資源消耗。通過重複利用已創建的線程降低線程創建和銷燬造成的消耗。
  2. 提高響應速度。當任務到達時,任務可以不需要等到線程創建就能立即執行。
  3. 提高線程的可管理性。線程是稀缺資源,如果無限制的創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一的分配,調優和監控。

  Executor線程池框架的最大優點是把任務的提交和執行解耦。客戶端將要執行的任務封裝成Task,然後提交即可。而Task如何執行客戶端則是透明的。具體點講,提交一個Callable對象給ExecutorService(如最常用的線程池ThreadPoolExecutor),將得到一個Future對象,調用Future對象的get方法等待執行結果。 
  下圖是線程池所涉及到的所有類的結構圖(右鍵查看大圖),先從整體把握下: 
這裏寫圖片描述
              圖1 線程池實現原理類結構圖

  上面這個圖是很複雜的,涉及到了線程池內部實現原理的所有類,不利於我們理解線程池如何使用。我們先從客戶端的角度出發,看看客戶端使用線程池所涉及到的類結構圖: 
這裏寫圖片描述
              圖2 線程池使用的基本類結構圖

  從圖一可知,實際的線程池類是實現ExecutorService接口的類,有ThreadPoolExecutor、ForkJoinPool和ScheduledThreadPoolExecutor。下面以常用的ThreadPoolExecutor爲例講解。

2 線程池實現步驟

2.1 線程池的創建

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">ThreadPoolExecutor</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> corePoolSize,
                          <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> maximumPoolSize,
                          <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

  參數說明:

  • corePoolSize(線程池的基本線程數): the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set.當提交一個任務到線程池時,線程池會創建一個線程來執行任務,即使其他空閒的基本線程能夠執行新任務也會創建線程,等到需要執行的任務數大於線程池基本大小時就不再創建。如果調用了線程池的prestartAllCoreThreads方法,線程池會提前創建並啓動所有基本線程。
  • maximumPoolSize(線程池最大線程數): the maximum number of threads to allow in the pool.線程池允許創建的最大線程數。如果任務隊列滿了,並且已創建的線程數小於最大線程數,則線程池會再創建新的線程執行任務。值得注意的是如果使用了無界的任務隊列這個參數就沒什麼效果。
  • keepAliveTime(線程活動保持時間):when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.線程池的工作線程空閒後,保持存活的時間。所以如果任務很多,並且每個任務執行的時間比較短,可以調大這個時間,提高線程的利用率。
  • TimeUnit(線程活動保持時間的單位):the time unit for the keepAliveTime argument. 可選的單位有天(DAYS),小時(HOURS),分鐘(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。
  • workQueue(任務隊列):the queue to use for holding tasks before they are executed. This queue will hold only the Runnable tasks submitted by the execute method.用於保存等待執行的任務的阻塞隊列。 可以選擇以下幾個阻塞隊列。 
      ArrayBlockingQueue:是一個基於數組結構的有界阻塞隊列,此隊列按 FIFO(先進先出)原則對元素進行排序。 
      LinkedBlockingQueue:一個基於鏈表結構的阻塞隊列,此隊列按FIFO (先進先出) 排序元素,吞吐量通常要高於ArrayBlockingQueue。靜態工廠方法Executors.newFixedThreadPool()使用了這個隊列。 
      SynchronousQueue:一個不存儲元素的阻塞隊列。每個插入操作必須等到另一個線程調用移除操作,否則插入操作一直處於阻塞狀態,吞吐量通常要高於LinkedBlockingQueue,靜態工廠方法Executors.newCachedThreadPool使用了這個隊列。 
      PriorityBlockingQueue:一個具有優先級的無限阻塞隊列。
  • ThreadFactory:用於設置創建線程的工廠,可以通過線程工廠給每個創建出來的線程設置更有意義的名字。
  • RejectedExecutionHandler(飽和策略):當隊列和線程池都滿了,說明線程池處於飽和狀態,那麼必須採取一種策略處理提交的新任務。這個策略默認情況下是AbortPolicy,表示無法處理新任務時拋出異常。以下是JDK1.5提供的四種策略。 
      AbortPolicy:直接拋出異常。 
      CallerRunsPolicy:只用調用者所在線程來運行任務。 
      DiscardOldestPolicy:丟棄隊列裏最近的一個任務,並執行當前任務。 
      DiscardPolicy:不處理,丟棄掉。 
      當然也可以根據應用場景需要來實現RejectedExecutionHandler接口自定義策略。如記錄日誌或持久化不能處理的任務。

  由此可見,創建一個線程所需的參數很多,線程池爲我們提供了類Executors的靜態工廠方法以創建不同類型的線程池。 
newFixedThreadPool可以生成固定大小的線程池; 
newCachedThreadPool可以生成一個無界、可以自動回收的線程池; 
newSingleThreadScheduledExecutor可以生成一個單個線程的線程池; 
newScheduledThreadPool還可以生成支持週期任務的線程池。

2.2 向線程池提交任務

  有兩種方式提交任務: 
1.使用void execute(Runnable command)方法提交任務 
execute方法返回類型爲void,所以沒有辦法判斷任務是否被線程池執行成功。

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Runnable task = new Runnable() {
    @Override
    public void run() {
        System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Task is running by "</span> + Thread<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.currentThread</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getName</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"線程池正在執行的線程數:"</span> + threadPoolExecutor<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getActiveCount</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    }
}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.execute</span>(task)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

2.使用submit方法提交任務 
Future<?> submit(Runnable task);<T> Future<T> submit(Runnable task, T result);和 Future<T> submit(Callable<T> task);會返回一個Future,可以通過這個future來判斷任務是否執行成功,通過future的get方法來獲取返回值,get方法會阻塞直到任務完成,而使用get(long timeout, TimeUnit unit)方法則會阻塞一段時間後立即返回,這時有可能任務沒有執行完。

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Future<?> future = threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.submit</span>(task)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
try {
    Object result = future<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.get</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"任務是否完成:"</span> + future<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isDone</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"返回的結果爲:"</span> + result)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
} catch (InterruptedException | ExecutionException e) {
    e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
} finally {
    // 關閉線程池
    threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.shutdown</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

2.3 線程池關閉

  1. shutdown()方法:這個方法會平滑地關閉ExecutorService,當我們調用這個方法時,ExecutorService停止接受任何新的任務且等待已經提交的任務執行完成(已經提交的任務會分兩類:一類是已經在執行的,另一類是還沒有開始執行的),當所有已經提交的任務執行完畢後將會關閉ExecutorService。
  2. awaitTermination(long timeout, TimeUnit unit)方法:這個方法有兩個參數,一個是timeout即超時時間,另一個是unit即時間單位。這個方法會使當前關閉線程池的線程等待timeout時長,當超過timeout時間後,則去監測ExecutorService是否已經關閉,若關閉則返回true,否則返回false。一般情況下會和shutdown方法組合使用。
  3. shutdownNow()方法:這個方法會強制關閉ExecutorService,它將取消所有運行中的任務和在工作隊列中等待的任務,這個方法返回一個List列表,列表中返回的是等待在工作隊列中的任務。
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">// <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4.</span> 關閉線程池
threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.shutdown</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
// hreadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.shutdownNow</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"線程池是否關閉:"</span> + threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isShutdown</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
try {
    //當前線程阻塞<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>ms後,去檢測線程池是否終止,終止則返回true
    while(!threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.awaitTermination</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>, TimeUnit<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.MILLISECONDS</span>)) {
        System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"檢測線程池是否終止:"</span> + threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isTerminated</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    }
} catch (InterruptedException e) {
    e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}
System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"線程池是否終止:"</span> + threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isTerminated</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

  完整案例:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">package <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.markliu</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.concurrent</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.threadpool</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

import java<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.util</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.concurrent</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ExecutionException</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
import java<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.util</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.concurrent</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ExecutorService</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
import java<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.util</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.concurrent</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Executors</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
import java<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.util</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.concurrent</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Future</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
import java<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.util</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.concurrent</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ThreadPoolExecutor</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
import java<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.util</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.concurrent</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.TimeUnit</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

public class ThreadPoolDemo1 {

    public static void main(String[] args) {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*
         * 1. 創建線程池
         * 
         * 創建一個固定線程數目的線程池。corePoolSize = maximumPoolSize = 5
         * 即線程池的基本線程數和最大線程數相等。
         * 相當於:
         * new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
         */</span>
        ExecutorService threadPool = Executors<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.newFixedThreadPool</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*
         *  2. 封裝任務並提交給線程池
         */</span>
        ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) threadPool<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        Runnable task = new Runnable() {
            @Override
            public void run() {
                System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Task is running by "</span> + Thread<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.currentThread</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getName</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"線程池正在執行的線程數:"</span> + threadPoolExecutor<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getActiveCount</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                try {
                    TimeUnit<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.SECONDS</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.sleep</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                } catch (InterruptedException e) {
                    e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                }
            }
        }<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*
         * Starts all core threads, causing them to idly wait for work. 
         * This overrides the default policy of starting core threads 
         * only when new tasks are executed.
         */</span>
        int count = threadPoolExecutor<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.prestartAllCoreThreads</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"開啓的所有core線程數:"</span> + count)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"線程池當前線程數:"</span> + threadPoolExecutor<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getPoolSize</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"線程池的core number of threads:"</span> + threadPoolExecutor<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getCorePoolSize</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"線程池中的最大線程數:"</span> + threadPoolExecutor<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getLargestPoolSize</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        // <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3.</span> 執行,獲取返回結果
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
         * execute方式提交任務
         */</span>
        // threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.execute</span>(task)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
         * submit方式提交任務
         */</span>
        Future<?> future = threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.submit</span>(task)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        try {
            // 阻塞,等待線程執行完成,並獲得結果
            Object result = future<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.get</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"任務是否完成:"</span> + future<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isDone</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"返回的結果爲:"</span> + result)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        } catch (InterruptedException | ExecutionException e) {
            e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        } finally {
            System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"線程池中已經執行完的任務數:"</span> + threadPoolExecutor<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getCompletedTaskCount</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            // <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4.</span> 關閉線程池
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*
             * shutdown方法平滑地關閉線程池,將線程池的狀態設爲:SHUTDOWN
             * 停止接受任何新的任務且等待已經提交的任務執行完成,當所有已經
             * 提交的任務執行完畢後將會關閉線程池
             */</span>
            threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.shutdown</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*
             *  shutdownNow方法強制關閉線程池,將線程池狀態設置爲:STOP
             *  取消所有運行中的任務和在工作隊列中等待的任務,並返回所有未執行的任務List
             */</span>
            // hreadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.shutdownNow</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"線程池是否關閉:"</span> + threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isShutdown</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            try {
                //當前線程阻塞<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>ms後,去檢測線程池是否終止,終止則返回true
                while(!threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.awaitTermination</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>, TimeUnit<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.MILLISECONDS</span>)) {
                    System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"檢測線程池是否終止:"</span> + threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isTerminated</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
                }
            } catch (InterruptedException e) {
                e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
            }
            System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"線程池是否終止:"</span> + threadPool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isTerminated</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        }
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li></ul>

3 線程池的執行流程分析

  線程池的主要工作流程如下圖: 
    這裏寫圖片描述 
  當提交一個新任務到線程池時,線程池的處理流程如下: 
首先線程池判斷“基本線程池”(corePoolSize)是否已滿?沒滿,創建一個工作線程來執行任務。滿了,則進入下個流程。 
其次線程池判斷工作隊列(workQueue)是否已滿?沒滿,則將新提交的任務存儲在工作隊列裏。滿了,則進入下個流程。 
最後線程池判斷整個線程池的線程數是否已超過maximumPoolSize?沒滿,則創建一個新的工作線程來執行任務,滿了,則交給拒絕策略來處理這個任務。 
(我的理解:提交任務—>如果線程數未達到corePoolSize,則創建線程執行任務—>如果達到corePoolSize,仍讓提交了任務,則會有任務等待,所以將任務保存在任務隊列中,直到任務隊列workQueue已滿—>如果workQueue已滿,仍然有任務提交,但未達到最大線程數,則繼續創建線程執行任務,直到線程數達到maximumPoolSize,如果達到了maximumPoolSize,則根據飽和策略拒絕該任務。這也就解釋了爲什麼有了corePoolSize還有maximumPoolSize的原因。) 
  關於線程池的工作原理後期從源代碼分析。

4 線程池的監控

  通過線程池提供的參數進行監控: 
taskCount:線程池需要執行的任務數量。 
completedTaskCount:線程池在運行過程中已完成的任務數量。小於或等於taskCount。 
largestPoolSize:線程池曾經創建過的最大線程數量。通過這個數據可以知道線程池是否滿過。如等於線程池的最大大小,則表示線程池曾經滿了。 
getPoolSize:線程池的線程數量。如果線程池不銷燬的話,池裏的線程不會自動銷燬,所以這個大小隻增不減 
getActiveCount:獲取活動的線程數。

  通過繼承線程池並重寫線程池的beforeExecute,afterExecute和terminated方法,可以在任務執行前,執行後和線程池關閉前幹一些事情。如監控任務的平均執行時間,最大執行時間和最小執行時間等。這幾個方法在線程池裏是空方法。

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * 給定的Thread執行Runnable之前調用此方法
     *
     *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> t the thread that will run task {@code r}
     *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> r the task that will be executed
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">beforeExecute</span>(Thread t, Runnable r) { }
    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * 給定的Runnable完成後執行此方法
     * This method is invoked by the thread that executed the task. 
     *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> r the runnable that has completed
     *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> t the exception that caused termination, or null if
     * execution completed normally
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">afterExecute</span>(Runnable r, Throwable t) { }
    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * 當Executor終止時調用此方法.  
     * 注意:方法中子類應調用super.terminated()
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">terminated</span>() { }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li></ul>

  例如:

<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ExtendedExecutor</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ThreadPoolExecutor</span> {</span>
      <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// ...</span>
      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (t == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && r <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">instanceof</span> Future<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;"><?</span>>) {
          <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
            Object result = ((Future<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;"><?</span>>) r).get();
          } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (CancellationException ce) {
              t = ce;
          } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (ExecutionException ee) {
              t = ee.getCause();
          } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (InterruptedException ie) {
              Thread.currentThread().interrupt(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// ignore/reset</span>
          }
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (t != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>)
          System.out.println(t);
      }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li></li></ul>
發佈了39 篇原創文章 · 獲贊 3 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章