java中Executor、ExecutorService、ThreadPoolExecutor介紹

1.Excutor

     源碼非常簡單,只有一個execute(Runnable command)回調接口 

public interface Executor {

    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the <tt>Executor</tt> implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     * accepted for execution.
     * @throws NullPointerException if command is null
     */
    void execute(Runnable command);
}   

    執行已提交的 Runnable 任務對象。此接口提供一種將任務提交與每個任務將如何運行的機制(包括線程使用的細節、調度等)分離開來的方法。通常使用 Executor 而不是顯式地創建線程。例如,可能會使用以下方法,而不是爲一組任務中的每個任務調用 new Thread(new(RunnableTask())).start()

 Executor executor = anExecutor;
 executor.execute(new RunnableTask1());
 executor.execute(new RunnableTask2());
 ...
 
不過,Executor 接口並沒有嚴格地要求執行是異步的。在最簡單的情況下,執行程序可以在調用方的線程中立即運行已提交的任務:
 class DirectExecutor implements Executor {
     public void execute(Runnable r) {
         r.run();
     }
 }
更常見的是,任務是在某個不是調用方線程的線程中執行的。以下執行程序將爲每個任務生成一個新線程。
 class ThreadPerTaskExecutor implements Executor {
     public void execute(Runnable r) {
         new Thread(r).start();
     }
 }
許多 Executor 實現都對調度任務的方式和時間強加了某種限制。以下執行程序使任務提交與第二個執行程序保持連續,這說明了一個複合執行程序。
 class SerialExecutor implements Executor {
     final Queue<Runnable> tasks = new LinkedBlockingQueue<Runnable>();
     final Executor executor;
     Runnable active;

     SerialExecutor(Executor executor) {
         this.executor = executor;
     }

     public synchronized void execute(final Runnable r) {
         tasks.offer(new Runnable() {
             public void run() {
                 try {
                     r.run();
                 } finally {
                     scheduleNext();
                 }
             }
         });
         if (active == null) {
             scheduleNext();
         }
     }

     protected synchronized void scheduleNext() {
         if ((active = tasks.poll()) != null) {
             executor.execute(active);
         }
     }
 }

2.ExcutorService接口
         ExecutorService提供了管理終止的方法,以及可爲跟蹤一個或多個異步任務執行狀況而生成 Future 的方法。
可以關閉 ExecutorService,這將導致其拒絕新任務。提供兩個方法來關閉 ExecutorService。
shutdown()方法在終止前允許執行以前提交的任務,而 shutdownNow() 方法阻止等待任務的啓動並試圖停止當前正在執行的任務。在終止後,執行程序沒有任務在執行,也沒有任務在等待執行,並且無法提交新任務。應該關閉未使用的 ExecutorService以允許回收其資源
通過創建並返回一個可用於取消執行和/或等待完成的 Future,方法submit擴展了基本方法 Executor.execute(java.lang.Runnable)方法 invokeAny 和 invokeAll 是批量執行的最常用形式它們執行任務 collection,然後等待至少一個,
或全部任務完成(可使用 ExecutorCompletionService類來編寫這些方法的自定義變體)。
Executors類爲創建ExecutorService提供了便捷的工廠方法。
注意1:它只有一個直接實現類ThreadPoolExecutor和間接實現類ScheduledThreadPoolExecutor。
關於ThreadPoolExecutor的更多內容請參考ThreadPoolExecutor
關於ScheduledThreadPoolExecutor的更多內容請參考ScheduledThreadPoolExecutor
用法示例
下面給出了一個網絡服務的簡單結構,這裏線程池中的線程作爲傳入的請求。它使用了預先配置的 Executors.newFixedThreadPool(int) 工廠方法:
<span style="line-height: 23px; color: rgb(0, 0, 136);">class</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">NetworkService</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">implements</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">Runnable</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">private</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">final</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">ServerSocket</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> serverSocket</span><span style="line-height: 23px; color: rgb(102, 102, 0);">;</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">private</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">final</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">ExecutorService</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> pool</span><span style="line-height: 23px; color: rgb(102, 102, 0);">;</span><span style="line-height: 23px; color: rgb(0, 0, 0);">

<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">public</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">NetworkService</span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(0, 0, 136);">int</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> port</span><span style="line-height: 23px; color: rgb(102, 102, 0);">,</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">int</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> poolSize</span><span style="line-height: 23px; color: rgb(102, 102, 0);">)</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">       </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">throws</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">IOException</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     serverSocket </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">=</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">new</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">ServerSocket</span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(0, 0, 0);">port</span><span style="line-height: 23px; color: rgb(102, 102, 0);">);</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     pool </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">=</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">Executors</span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">newFixedThreadPool</span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(0, 0, 0);">poolSize</span><span style="line-height: 23px; color: rgb(102, 102, 0);">);</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);">

<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">public</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">void</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> run</span><span style="line-height: 23px; color: rgb(102, 102, 0);">()</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(136, 0, 0);">// run the service</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">try</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">       </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">for</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">(;;)</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">         pool</span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">execute</span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(0, 0, 136);">new</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">Handler</span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(0, 0, 0);">serverSocket</span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">accept</span><span style="line-height: 23px; color: rgb(102, 102, 0);">()));</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">       </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">catch</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(102, 0, 102);">IOException</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> ex</span><span style="line-height: 23px; color: rgb(102, 102, 0);">)</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">       pool</span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">shutdown</span><span style="line-height: 23px; color: rgb(102, 102, 0);">();</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln"> </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);">

<span class="pln"> </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">class</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">Handler</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">implements</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">Runnable</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">private</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">final</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">Socket</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> socket</span><span style="line-height: 23px; color: rgb(102, 102, 0);">;</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(102, 0, 102);">Handler</span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(102, 0, 102);">Socket</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> socket</span><span style="line-height: 23px; color: rgb(102, 102, 0);">)</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">this</span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">socket </span><span style="line-height: 23px; color: rgb(102, 102, 0);">=</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> socket</span><span style="line-height: 23px; color: rgb(102, 102, 0);">;</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">public</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">void</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> run</span><span style="line-height: 23px; color: rgb(102, 102, 0);">()</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 23px; color: rgb(136, 0, 0);">// read and service request on socket</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln"> </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln"> </span></span>
 下列方法分兩個階段關閉 ExecutorService。第一階段調用 shutdown 拒絕傳入任務,然後等60秒後,任務還沒執行完成,就調用 shutdownNow(如有必要)取消所有遺留的任務
<span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">void</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> shutdownAndAwaitTermination</span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(102, 0, 102);">ExecutorService</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> pool</span><span style="line-height: 23px; color: rgb(102, 102, 0);">)</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   pool</span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">shutdown</span><span style="line-height: 23px; color: rgb(102, 102, 0);">();</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(136, 0, 0);">// Disable new tasks from being submitted</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">try</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 23px; color: rgb(136, 0, 0);">// Wait a while for existing tasks to terminate</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">if</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">(!</span><span style="line-height: 23px; color: rgb(0, 0, 0);">pool</span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">awaitTermination</span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(0, 102, 102);">60</span><span style="line-height: 23px; color: rgb(102, 102, 0);">,</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">TimeUnit</span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">SECONDS</span><span style="line-height: 23px; color: rgb(102, 102, 0);">))</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">       pool</span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">shutdownNow</span><span style="line-height: 23px; color: rgb(102, 102, 0);">();</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(136, 0, 0);">// Cancel currently executing tasks</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">       </span></span><span style="line-height: 23px; color: rgb(136, 0, 0);">// Wait a while for tasks to respond to being cancelled</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">       </span></span><span style="line-height: 23px; color: rgb(0, 0, 136);">if</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">(!</span><span style="line-height: 23px; color: rgb(0, 0, 0);">pool</span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">awaitTermination</span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(0, 102, 102);">60</span><span style="line-height: 23px; color: rgb(102, 102, 0);">,</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 0, 102);">TimeUnit</span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">SECONDS</span><span style="line-height: 23px; color: rgb(102, 102, 0);">))</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">           </span></span><span style="line-height: 23px; color: rgb(102, 0, 102);">System</span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">err</span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">println</span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(0, 136, 0);">"Pool did not terminate"</span><span style="line-height: 23px; color: rgb(102, 102, 0);">);</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(0, 0, 136);">catch</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">(</span><span style="line-height: 23px; color: rgb(102, 0, 102);">InterruptedException</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> ie</span><span style="line-height: 23px; color: rgb(102, 102, 0);">)</span><span style="line-height: 23px; color: rgb(0, 0, 0);"> </span><span style="line-height: 23px; color: rgb(102, 102, 0);">{</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 23px; color: rgb(136, 0, 0);">// (Re-)Cancel if current thread also interrupted</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     pool</span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">shutdownNow</span><span style="line-height: 23px; color: rgb(102, 102, 0);">();</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 23px; color: rgb(136, 0, 0);">// Preserve interrupt status</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 23px; color: rgb(102, 0, 102);">Thread</span><span style="line-height: 23px; color: rgb(102, 102, 0);">.</span><span style="line-height: 23px; color: rgb(0, 0, 0);">currentThread</span><span style="line-height: 23px; color: rgb(102, 102, 0);">().</span><span style="line-height: 23px; color: rgb(0, 0, 0);">interrupt</span><span style="line-height: 23px; color: rgb(102, 102, 0);">();</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln"> </span></span><span style="line-height: 23px; color: rgb(102, 102, 0);">}</span><span style="line-height: 23px; color: rgb(0, 0, 0);">
<span class="pln"> </span></span>
 內存一致性效果:線程中向 ExecutorService 提交 Runnable 或 Callable 任務之前的操作 happen-before 由該任務所提取的所有操作,
 後者依次 happen-before 通過 Future.get() 獲取的結果。
 主要函數
 void shutdown()
    啓動一個關閉命令,不再接受新任務,當所有已提交任務執行完後,就關閉。如果已經關閉,則調用沒有其他作用。
    拋出:
        SecurityException - 如果安全管理器存在並且關閉,此 ExecutorService 可能操作某些不允許調用者修改的線程(因爲它沒有保持 RuntimePermission("modifyThread")),或者安全管理器的 checkAccess 方法拒絕訪問。
List<Runnable> shutdownNow()
    試圖停止所有正在執行的活動任務,暫停處理正在等待的任務,並返回等待執行的任務列表。
    無法保證能夠停止正在處理的活動執行任務,但是會盡力嘗試。例如,通過 Thread.interrupt() 來取消典型的實現,所以任何任務無法響應中斷都可能永遠無法終止。
    返回:
        從未開始執行的任務的列表 
    拋出:
        SecurityException - 如果安全管理器存在並且關閉,
        此 ExecutorService 可能操作某些不允許調用者修改的線程(因爲它沒有保持 RuntimePermission("modifyThread")),
        或者安全管理器的 checkAccess 方法拒絕訪問。
注意1: 它會返回等待執行的任務列表。
注意2: 無法保證能夠停止正在處理的活動執行任務,但是會盡力嘗試。例如,通過 Thread.interrupt() 來取消,
所以任何任務無法響應中斷都可能永遠無法終止。

boolean isShutdown()
    如果此執行程序已關閉,則返回 true。
    返回:
        如果此執行程序已關閉,則返回 true
boolean isTerminated()
    如果關閉後所有任務都已完成,則返回 true。注意,除非首先調用 shutdown 或 shutdownNow,否則 isTerminated 永不爲 true。
    返回:
        如果關閉後所有任務都已完成,則返回 true
boolean awaitTermination(long timeout,TimeUnit unit) throws InterruptedException
        等待(阻塞)直到關閉或最長等待時間或發生中斷
    參數:
        timeout - 最長等待時間
        unit - timeout 參數的時間單位 
    返回:
        如果此執行程序終止,則返回 true;如果終止前超時期滿,則返回 false 
    拋出:
        InterruptedException - 如果等待時發生中斷
注意1:如果此執行程序終止(關閉),則返回 true;如果終止前超時期滿,則返回 false
<T> Future<T> submit(Callable<T> task)
    提交一個返回值的任務用於執行,返回一個表示任務的未決結果的 Future。該 Future 的 get 方法在成功完成時將會返回該任務的結果。
    如果想立即阻塞任務的等待,則可以使用 result = exec.submit(aCallable).get(); 形式的構造。
    注:Executors 類包括了一組方法,可以轉換某些其他常見的類似於閉包的對象,
    例如,將 PrivilegedAction 轉換爲 Callable 形式,這樣就可以提交它們了。
    參數:
        task - 要提交的任務 
    返回:
        表示任務等待完成的 Future 
    拋出:
        RejectedExecutionException - 如果任務無法安排執行 
        NullPointerException - 如果該任務爲 null
注意:關於submit的使用和Callable可以參閱《使用Callable返回結果
<T> Future<T> submit(Runnable task,T result)
    提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future。該 Future 的 get 方法在成功完成時將會返回給定的結果。
    參數:
        task - 要提交的任務
        result - 返回的結果 
    返回:
        表示任務等待完成的 Future 
    拋出:
        RejectedExecutionException - 如果任務無法安排執行 
        NullPointerException - 如果該任務爲 null
注意:關於submit的使用可以參閱《Callable》
Future<?> submit(Runnable task)
    提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future。該 Future 的 get 方法在成功 完成時將會返回 null。
    參數:
        task - 要提交的任務 
    返回:
        表示任務等待完成的 Future 
    拋出:
        RejectedExecutionException - 如果任務無法安排執行 
        NullPointerException - 如果該任務爲 null
注意:關於submit的使用可以參閱《使用Callable返回結果
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)    throws InterruptedException
    執行給定的任務,當所有任務完成時,返回保持任務狀態和結果的 Future 列表。返回列表的所有元素的 Future.isDone() 爲 true。
    注意,可以正常地或通過拋出異常來終止已完成 任務。如果正在進行此操作時修改了給定的 collection,則此方法的結果是不確定的。
    參數:
        tasks - 任務 collection 
    返回:
        表示任務的 Future 列表,列表順序與給定任務列表的迭代器所生成的順序相同,每個任務都已完成。 
    拋出:
        InterruptedException - 如果等待時發生中斷,在這種情況下取消尚未完成的任務。 
        NullPointerException - 如果任務或其任意元素爲 null 
        RejectedExecutionException - 如果所有任務都無法安排執行
注意1:該方法會一直阻塞直到所有任務完成。
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                              long timeout,
                              TimeUnit unit)
                          throws InterruptedException
    執行給定的任務,當所有任務完成或超時期滿時(無論哪個首先發生),返回保持任務狀態和結果的 Future 列表。返回列表的所有元素的 Future.isDone() 爲 true。一旦返回後,即取消尚未完成的任務。注意,可以正常地或通過拋出異常來終止已完成 任務。如果此操作正在進行時修改了給定的 collection,則此方法的結果是不確定的。
    參數:
        tasks - 任務 collection
        timeout - 最長等待時間
        unit - timeout 參數的時間單位 
    返回:
        表示任務的 Future 列表,列表順序與給定任務列表的迭代器所生成的順序相同。
        如果操作未超時,則已完成所有任務。如果確實超時了,則某些任務尚未完成。 
    拋出:
        InterruptedException - 如果等待時發生中斷,在這種情況下取消尚未完成的任務 
        NullPointerException - 如果任務或其任意元素或 unit 爲 null 
        RejectedExecutionException - 如果所有任務都無法安排執行
注意1:該方法會一直阻塞直到所有任務完成或超時。
注意2:如果確實超時了,則某些任務尚未完成。【那麼這些尚未完成的任務應該被系統取消】。
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
            throws InterruptedException,
                   ExecutionException
    執行給定的任務,如果某個任務已成功完成(也就是未拋出異常),則返回其結果。一旦正常或異常返回後,則取消尚未完成的任務。
    如果此操作正在進行時修改了給定的 collection,則此方法的結果是不確定的。
    參數:
        tasks - 任務 collection 
    返回:
        某個任務返回的結果 
    拋出:
        InterruptedException - 如果等待時發生中斷 
        NullPointerException - 如果任務或其任意元素爲 null 
        IllegalArgumentException - 如果任務爲空 
        ExecutionException - 如果沒有任務成功完成 
        RejectedExecutionException - 如果任務無法安排執行
注意1:該方法會一直阻塞直到有一個任務完成。
注意2:一旦正常或異常返回後,則取消尚未完成的任務
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
                long timeout,
                TimeUnit unit)
            throws InterruptedException,
                   ExecutionException,
                   TimeoutException

    執行給定的任務,如果在給定的超時期滿前某個任務已成功完成(也就是未拋出異常),則返回其結果。一旦正常或異常返回後,則取消尚未完成的任務。如果此操作正在進行時修改了給定的 collection,則此方法的結果是不確定的。

    參數:
        tasks - 任務 collection
        timeout - 最長等待時間
        unit - timeout 參數的時間單位 
    返回:
        某個任務返回的結果 
    拋出:
        InterruptedException - 如果等待時發生中斷 
        NullPointerException - 如果任務或其任意元素或 unit 爲 null 
        TimeoutException - 如果在所有任務成功完成之前給定的超時期滿 
        ExecutionException - 如果沒有任務成功完成 
        RejectedExecutionException - 如果任務無法安排執行
注意1該方法會一直阻塞直到有一個任務完成。
注意2:一旦正常或異常返回後,則取消尚未完成的任務

3.ThreadPoolExecutor
ThreadPoolExecutorExecutorService的一個實現類,它使用可能的幾個池線程之一執行每個提交的任務,通常使用 Executors 工廠方法配置。
線程池可以解決兩個不同問題:由於減少了每個任務調用的開銷,它們通常可以在執行大量異步任務時提供增強的性能,並且還可以提供綁定和管理資源(包括執行任務集時使用的線程)的方法
每個 ThreadPoolExecutor 還維護着一些基本的統計數據,如完成的任務數。爲了便於跨大量上下文使用,此類提供了很多可調整的參數和擴展鉤子 (hook)。
但是,強烈建議程序員使用較爲方便的 Executors 工廠方法 Executors.newCachedThreadPool()無界線程池,可以進行自動線程回收)、Executors.newFixedThreadPool(int)固定大小線程池)和 Executors.newSingleThreadExecutor()單個後臺線程),
它們均爲大多數使用場景預定義了設置。否則,在手動配置和調整此類時,使用以下指導:
核心和最大池大小
    ThreadPoolExecutor將根據corePoolSize(參見 getCorePoolSize())和 maximumPoolSize(參見 getMaximumPoolSize())
    設置的邊界自動調整池大小。當新任務在方法 execute(java.lang.Runnable) 中提交時,如果運行的線程少於 corePoolSize,    則創建新線程來處理請求,即使有線程是空閒的。
    如果運行的線程多於 corePoolSize 而少於 maximumPoolSize,則僅當隊列滿時才創建新線程。
    如果設置的 
corePoolSize 和 maximumPoolSize 相同,則創建了固定大小的線程池。
    如果將 
maximumPoolSize 設置爲基本的無界值(如 Integer.MAX_VALUE),則允許池適應任意數量的併發任務。
    在大多數情況下,核心和最大池大小僅基於構造來設置,不過也可以使用 
setCorePoolSize(int)  setMaximumPoolSize(int) 進行動態更改。 
注意1:在新任務被提交時,如果運行的core線程少於corePoolSize,才創建新core線程。並不是一開始就創建corePoolSize個core線程。
注意2:"如果運行的線程多於corePoolSize 而少於 maximumPoolSize,則僅當隊列滿時才創建新線程"
按需構造
    核心線程最初只是在新任務到達時才被ThreadPoolExecutor創建和啓動的,
    但是也可以手動調用方法 prestartCoreThread() 或 prestartAllCoreThreads()來的提前啓動核心線程
    如果構造帶有非空隊列的池,這時則可能希望預先啓動線程。
注意1:核心線程即core線程,只有當前線程數小於等於corePoolSize時,這時的線程才叫核心線程。
創建新線程
    使用ThreadFactory創建新線程。如果沒有另外說明,則使用 Executors.defaultThreadFactory() 創建線程,他們在同一個ThreadGroup中
    並且這些線程具有相同的 NORM_PRIORITY 優先級和非守護進程狀態。

    通過提供不同的 ThreadFactory,可以改變線程的名稱、線程組、優先級、守護進程狀態,等等。
    如果從 newThread 返回 null 時 ThreadFactory 未能創建線程,則執行程序將繼續運行,但不能執行任何任務。
注意1:可以指定創建線程的ThreadFactory,默認的是使用Executors.defaultThreadFactory()來創建線程,所有的線程都在一個ThreadGroup中。
保持活動時間
    如果池中當前有多於corePoolSize 的線程,則這些多出的線程在空閒時間超過 keepAliveTime 時將會終止
    (參見 
getKeepAliveTime(java.util.concurrent.TimeUnit))。這提供了當池處於非活動狀態時減少資源消耗的方法。
    如果池後來變得更爲活動,則可以創建新的線程。也可以使用方法 setKeepAliveTime(long, java.util.concurrent.TimeUnit) 動態地更改此參數。

    如果把值設爲Long.MAX_VALUE TimeUnit.NANOSECONDS 的話,空閒線程不會被回收直到ThreadPoolExecutor爲Terminate。
    默認情況下,保持活動策略只在有多於corePoolSizeThreads 的線程時應用。
    但是隻要 keepAliveTime 值非 0,allowCoreThreadTimeOut(boolean) 方法也可將此超時策略應用於核心線程。
注意1:setKeepAliveTime(long, java.util.concurrent.TimeUnit)用於設置空閒線程最長的活動時間,
    即如果空閒時間超過設定值,就停掉該線程,對該線程進行回收。
    該策略默認只對非內核線程有用(即當前線程數大於corePoolSize),
    可以調用allowCoreThreadTimeOut(boolean)方法將此超時策略擴大到核心線程
注意2:如果把值設爲Long.MAX_VALUE TimeUnit.NANOSECONDS的話,空閒線程不會被回收直到ThreadPoolExecutor爲Terminate。
排隊
    所有 BlockingQueue 都可用於傳輸和保持提交的任務。可以使用此隊列與池大小進行交互:
        * 如果運行的線程少於 corePoolSize,則 Executor 始終首選添加新的線程,而不進行排隊。
        * 如果運行的線程等於或多於 corePoolSize,則 Executor 始終首選將請求加入隊列,而不添加新的線程。
        * 如果無法將請求加入隊列,則創建新的線程,除非創建此線程超出 maximumPoolSize,在這種情況下,任務將被拒絕

    排隊有三種通用策略:
    1. 直接提交。工作隊列的默認選項是 SynchronousQueue,它將任務直接提交給線程而不保持它們。
       在此,如果不存在可用於立即運行任務的線程,則試圖把任務加入隊列將失敗,因此會構造一個新的線程。
       此策略可以避免在處理可能具有內部依賴性的請求集時出現鎖。
       直接提交通常要求無界maximumPoolSizes以避免拒絕新提交的任務。
       當命令以超過隊列所能處理的平均數連續到達時,此策略允許線程無界的增長。
注意1:此策略允許線程無界的增長。
    2. 無界隊列。使用無界隊列(例如,不具有預定義容量的 LinkedBlockingQueue)將導致在所有 corePoolSize 線程都忙時新任務在隊列中等待。
        這樣,創建的線程就不會超過 corePoolSize。(因此,maximumPoolSize 的值也就無效了。)
        當每個任務完全獨立於其他任務,即任務執行互不影響時,適合於使用無界隊列;例如,在 Web 頁服務器中。
        這種排隊可用於處理瞬態突發請求,當命令以超過隊列所能處理的平均數連續到達時,此策略允許隊列無限的增長。
注意1:此策略允許隊列無限的增長。
    3. 有界隊列。當使用有限的 maximumPoolSizes 時,有界隊列(如 ArrayBlockingQueue)有助於防止資源耗盡,但是可能較難調整和控制。
        隊列大小和最大池大小可能需要相互折衷:使用大型隊列和小型池可以最大限度地降低 CPU 使用率、操作系統資源和上下文切換開銷,
        但是可能導致人工降低吞吐量。如果任務頻繁阻塞(例如,如果它們是 I/O 邊界),則系統可能爲超過您許可的更多線程安排時間。
        使用小型隊列通常要求較大的池大小,CPU 使用率較高,但是可能遇到不可接受的調度開銷,這樣也會降低吞吐量。
被拒絕的任務
    當 Executor 已經關閉,或Executor將有限邊界用於最大線程和工作隊列容量,且已經飽和時,
    在方法 execute(java.lang.Runnable) 中提交的新任務將被拒絕。
    在以上兩種情況下,execute 方法都將調用其
    RejectedExecutionHandlerRejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) 方法。
    下面提供了四種預定義的處理程序策略
       1. 在默認的 ThreadPoolExecutor.AbortPolicy 中,處理程序遭到拒絕將拋出運行時RejectedExecutionException。
       2. 在
 ThreadPoolExecutor.CallerRunsPolicy中,線程調用運行該任務的 execute 本身。
       此策略提供簡單的反饋控制機制,能夠減緩新任務的提交速度。
       3. 在
ThreadPoolExecutor.DiscardPolicy中,不能執行的任務將被刪除。
       4. 在
ThreadPoolExecutor.DiscardOldestPolicy 中,如果執行程序尚未關閉,
       則位於工作隊列頭部的任務將被刪除,然後重試執行程序(如果再次失敗,則重複此過程)。

    定義和使用其他種類的RejectedExecutionHandler類也是可能的,但這樣做需要非常小心,尤其是當策略僅用於特定容量或排隊策略時
注意1:AbortPolicy,CallerRunsPolicy,DiscardPolicy和DiscardOldestPolicy都是rejectedExecution的一種實現。
    當然也可以自己定義個rejectedExecution實現。
鉤子 (hook) 方法
    此類提供 protected 可重寫的 beforeExecute(java.lang.Thread, java.lang.Runnable) 
    和 afterExecute(java.lang.Runnable, java.lang.Throwable) 方法,這兩種方法分別在執行每個任務之前和之後調用。
    它們可用於操縱執行環境;例如,重新初始化 ThreadLocal、蒐集統計信息或添加日誌條目。
    此外,還可以重寫方法 terminated() 來執行 Executor 完全終止後需要完成的所有特殊處理。
    如果鉤子 (hook) 或回調方法拋出異常,則ThreadPoolExecutor的所有線程將依次失敗並突然終止。 
隊列維護

    方法 getQueue() 允許出於監控和調試目的而訪問工作隊列。強烈反對出於其他任何目的而使用此方法。
    remove(java.lang.Runnable) 和 purge() 這兩種方法可用於在取消大量已排隊任務時幫助進行存儲回收。
注意1:如果任務取消,ThreadPoolExecutor應該自己是可以進行存儲回收的。
    取消的任務不會再次執行,但是它們可能在工作隊列中累積,直到worker線程主動將其移除
  外部使用remove(java.lang.Runnable)和purge()可以把它們立即從隊列中移除。
終止
    如果ThreadPoolExecutor在程序中沒有任何引用且沒有任何活動線程,它也不會自動 shutdown。
    如果希望確保回收線程(即使用戶忘記調用 shutdown()),則必須安排未使用的線程最終終止:

    設置適當保持活動時間,使用0核心線程的下邊界和/或設置 allowCoreThreadTimeOut(boolean)。
 擴展示例。此類的大多數擴展可以重寫一個或多個受保護的鉤子 (hook) 方法。例如,下面是一個添加了簡單的暫停/恢復功能的子類:
<span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><code style="line-height: 1em;"><span style="line-height: 22px; color: rgb(0, 0, 136);"><span class="kwd">class</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(102, 0, 102);"><span class="typ">PausableThreadPoolExecutor</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);"><span class="kwd">extends</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(102, 0, 102);"><span class="typ">ThreadPoolExecutor</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);"><span class="pun">{</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);"><span class="kwd">private</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);"><span class="kwd">boolean</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> isPaused</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);"><span class="pun">;</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);"><span class="kwd">private</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(102, 0, 102);"><span class="typ">ReentrantLock</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> pauseLock </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);"><span class="pun">=</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);"><span class="kwd">new</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(102, 0, 102);"><span class="typ">ReentrantLock</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);"><span class="pun">();</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);"><span class="kwd">private</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(102, 0, 102);"><span class="typ">Condition</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> unpaused </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);"><span class="pun">=</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> pauseLock</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);"><span class="pun">.</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln">newCondition</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);"><span class="pun">();</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);">

<span class="pln">   </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);"><span class="kwd">public</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(102, 0, 102);"><span class="typ">PausableThreadPoolExecutor</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);"><span class="pun">(...)</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);"><span class="pun">{</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);"><span class="kwd">super</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);"><span class="pun">(...);</span></span><span style="line-height: 22px; color: rgb(0, 0, 0);"><span class="pln"> </span></span></code><span style="line-height: 22px; color: rgb(0, 0, 0);">

<span class="pln">   </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);">protected</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(0, 0, 136);">void</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> beforeExecute</span><span style="line-height: 22px; color: rgb(102, 102, 0);">(</span><span style="line-height: 22px; color: rgb(102, 0, 102);">Thread</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> t</span><span style="line-height: 22px; color: rgb(102, 102, 0);">,</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 0, 102);">Runnable</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> r</span><span style="line-height: 22px; color: rgb(102, 102, 0);">)</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">{</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);">super</span><span style="line-height: 22px; color: rgb(102, 102, 0);">.</span><span style="line-height: 22px; color: rgb(0, 0, 0);">beforeExecute</span><span style="line-height: 22px; color: rgb(102, 102, 0);">(</span><span style="line-height: 22px; color: rgb(0, 0, 0);">t</span><span style="line-height: 22px; color: rgb(102, 102, 0);">,</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> r</span><span style="line-height: 22px; color: rgb(102, 102, 0);">);</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     pauseLock</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">.</span><span style="line-height: 22px; color: rgb(0, 0, 136);">lock</span><span style="line-height: 22px; color: rgb(102, 102, 0);">();</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);">try</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">{</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">       </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);">while</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">(</span><span style="line-height: 22px; color: rgb(0, 0, 0);">isPaused</span><span style="line-height: 22px; color: rgb(102, 102, 0);">)</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> unpaused</span><span style="line-height: 22px; color: rgb(102, 102, 0);">.</span><span style="line-height: 22px; color: rgb(0, 0, 0);">await</span><span style="line-height: 22px; color: rgb(102, 102, 0);">();</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">}</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(0, 0, 136);">catch</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">(</span><span style="line-height: 22px; color: rgb(102, 0, 102);">InterruptedException</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> ie</span><span style="line-height: 22px; color: rgb(102, 102, 0);">)</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">{</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">       t</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">.</span><span style="line-height: 22px; color: rgb(0, 0, 0);">interrupt</span><span style="line-height: 22px; color: rgb(102, 102, 0);">();</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">}</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(0, 0, 136);">finally</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">{</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">       pauseLock</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">.</span><span style="line-height: 22px; color: rgb(0, 0, 0);">unlock</span><span style="line-height: 22px; color: rgb(102, 102, 0);">();</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">}</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">}</span><span style="line-height: 22px; color: rgb(0, 0, 0);">

<span class="pln">   </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);">public</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(0, 0, 136);">void</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> pause</span><span style="line-height: 22px; color: rgb(102, 102, 0);">()</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">{</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     pauseLock</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">.</span><span style="line-height: 22px; color: rgb(0, 0, 136);">lock</span><span style="line-height: 22px; color: rgb(102, 102, 0);">();</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);">try</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">{</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">       isPaused </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">=</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(0, 0, 136);">true</span><span style="line-height: 22px; color: rgb(102, 102, 0);">;</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">}</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(0, 0, 136);">finally</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">{</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">       pauseLock</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">.</span><span style="line-height: 22px; color: rgb(0, 0, 0);">unlock</span><span style="line-height: 22px; color: rgb(102, 102, 0);">();</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">}</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">}</span><span style="line-height: 22px; color: rgb(0, 0, 0);">

<span class="pln">   </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);">public</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(0, 0, 136);">void</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> resume</span><span style="line-height: 22px; color: rgb(102, 102, 0);">()</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">{</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     pauseLock</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">.</span><span style="line-height: 22px; color: rgb(0, 0, 136);">lock</span><span style="line-height: 22px; color: rgb(102, 102, 0);">();</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 22px; color: rgb(0, 0, 136);">try</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">{</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">       isPaused </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">=</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(0, 0, 136);">false</span><span style="line-height: 22px; color: rgb(102, 102, 0);">;</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">       unpaused</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">.</span><span style="line-height: 22px; color: rgb(0, 0, 0);">signalAll</span><span style="line-height: 22px; color: rgb(102, 102, 0);">();</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">}</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(0, 0, 136);">finally</span><span style="line-height: 22px; color: rgb(0, 0, 0);"> </span><span style="line-height: 22px; color: rgb(102, 102, 0);">{</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">       pauseLock</span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">.</span><span style="line-height: 22px; color: rgb(0, 0, 0);">unlock</span><span style="line-height: 22px; color: rgb(102, 102, 0);">();</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">     </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">}</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln">   </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">}</span><span style="line-height: 22px; color: rgb(0, 0, 0);">
<span class="pln"> </span></span><span style="line-height: 22px; color: rgb(102, 102, 0);">}}</span>
 關於它的使用請參考《ExecutorService
Nested Classes
classThreadPoolExecutor.AbortPolicyA handler for rejected tasks that throws a RejectedExecutionException
classThreadPoolExecutor.CallerRunsPolicyA handler for rejected tasks that runs the rejected task directly in the calling thread of the execute method, unless the executor has been shut down, in which case the task is discarded. 
classThreadPoolExecutor.DiscardOldestPolicyA handler for rejected tasks that discards the oldest unhandled request and then retries execute, unless the executor is shut down, in which case the task is discarded. 
classThreadPoolExecutor.DiscardPolicyA handler for rejected tasks that silently discards the rejected task. 
主要構造函數
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue)

    用給定的初始參數和默認的線程工廠及被拒絕的執行處理程序創建新的 ThreadPoolExecutor。
    使用 Executors 工廠方法之一比使用此通用構造方法方便得多。
    參數:
        corePoolSize - 池中所保存的線程數,包括空閒線程。
        maximumPoolSize - 池中允許的最大線程數。
        keepAliveTime - 當線程數大於核心時,此爲終止前多餘的空閒線程等待新任務的最長時間。
        unit - keepAliveTime 參數的時間單位。
        workQueue - 執行前用於保持任務的隊列。此隊列僅保持由 execute 方法提交的 Runnable 任務。 
    拋出:
        IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小於 0,或者 maximumPoolSize 小於等於 0,
        或者 corePoolSize 大於 maximumPoolSize。 
        NullPointerException - 如果 workQueue 爲 null
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory)

    用給定的初始參數和默認被拒絕的執行處理程序創建新的 ThreadPoolExecutor。

    參數:
        corePoolSize - 池中所保存的線程數,包括空閒線程。
        maximumPoolSize - 池中允許的最大線程數。
        keepAliveTime - 當線程數大於核心時,此爲終止前多餘的空閒線程等待新任務的最長時間。
        unit - keepAliveTime 參數的時間單位。
        workQueue - 執行前用於保持任務的隊列。此隊列僅保持由 execute 方法提交的 Runnable 任務。
        threadFactory - 執行程序創建新線程時使用的工廠。 
    拋出:
        IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小於 0,或者 maximumPoolSize 小於等於 0,或者 corePoolSize 大於 maximumPoolSize。 
        NullPointerException - 如果 workQueue 或 threadFactory 爲 null。
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          RejectedExecutionHandler handler)

    用給定的初始參數和默認的線程工廠創建新的 ThreadPoolExecutor。

    參數:
        corePoolSize - 池中所保存的線程數,包括空閒線程。
        maximumPoolSize - 池中允許的最大線程數。
        keepAliveTime - 當線程數大於核心時,此爲終止前多餘的空閒線程等待新任務的最長時間。
        unit - keepAliveTime 參數的時間單位。
        workQueue - 執行前用於保持任務的隊列。此隊列僅由保持 execute 方法提交的 Runnable 任務。
        handler - 由於超出線程範圍和隊列容量而使執行被阻塞時所使用的處理程序。 
    拋出:
        IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小於 0,或者 maximumPoolSize 小於等於 0,
        或者 corePoolSize 大於 maximumPoolSize。
主要成員函數
public void execute(Runnable command)
    在將來某個時間執行給定任務。可以在新線程中或者在現有池線程中執行該任務。 如果無法將任務提交執行,或者因爲此執行程序已關閉,或者因爲已達到其容量,則該任務由當前 RejectedExecutionHandler 處理。
    參數:
        command - 要執行的任務。 
    拋出:
        RejectedExecutionException - 如果無法接收要執行的任務,則由 RejectedExecutionHandler 決定是否拋出 RejectedExecutionException 
        NullPointerException - 如果命令爲 null
public void shutdown()
    按過去執行已提交任務的順序發起一個有序的關閉,但是不接受新任務。如果已經關閉,則調用沒有其他作用。
    拋出:
        SecurityException - 如果安全管理器存在並且關閉此 ExecutorService 可能操作某些不允許調用者修改的線程(因爲它沒有 RuntimePermission("modifyThread")),或者安全管理器的 checkAccess 方法拒絕訪問。
public List<Runnable> shutdownNow()
    嘗試停止所有的活動執行任務、暫停等待任務的處理,並返回等待執行的任務列表。在從此方法返回的任務隊列中排空(移除)這些任務。
    並不保證能夠停止正在處理的活動執行任務,但是會盡力嘗試。 此實現通過 Thread.interrupt() 取消任務,所以無法響應中斷的任何任務可能永遠無法終止。
    返回:
        從未開始執行的任務的列表。 
    拋出:
        SecurityException - 如果安全管理器存在並且關閉此 ExecutorService 
        可能操作某些不允許調用者修改的線程(因爲它沒有 RuntimePermission("modifyThread")),
        或者安全管理器的 checkAccess 方法拒絕訪問。
public int prestartAllCoreThreads()
    啓動所有核心線程,使其處於等待工作的空閒狀態。僅當執行新任務時,此操作才重寫默認的啓動核心線程策略。
    返回:
        已啓動的線程數
public boolean allowsCoreThreadTimeOut()
    如果此池允許核心線程超時和終止,如果在 keepAlive 時間內沒有任務到達,新任務到達時正在替換(如果需要),則返回 true。當返回 true 時,適用於非核心線程的相同的保持活動策略也同樣適用於核心線程。當返回 false(默認值)時,由於沒有傳入任務,核心線程不會終止。
    返回:
        如果允許核心線程超時,則返回 true;否則返回 false
public void allowCoreThreadTimeOut(boolean value)
    如果在保持活動時間內沒有任務到達,新任務到達時正在替換(如果需要),則設置控制核心線程是超時還是終止的策略。當爲 false(默認值)時,由於沒有傳入任務,核心線程將永遠不會中止。當爲 true 時,適用於非核心線程的相同的保持活動策略也同樣適用於核心線程。爲了避免連續線程替換,保持活動時間在設置爲 true 時必須大於 0。通常應該在主動使用該池前調用此方法。
    參數:
        value - 如果應該超時,則爲 true;否則爲 false 
    拋出:
        IllegalArgumentException - 如果 value 爲 true 並且當前保持活動時間不大於 0。
public boolean remove(Runnable task)
    從執行程序的內部隊列中移除此任務(如果存在),從而如果尚未開始,則讓其不再運行。
    此方法可用作取消方案的一部分。它可能無法移除在放置到內部隊列之前已經轉換爲其他形式的任務。
    例如,使用 submit 輸入的任務可能被轉換爲維護 Future 狀態的形式。但是,在此情況下,purge() 方法可用於移除那些已被取消的 Future。
    參數:
        task - 要移除的任務 
    返回:
        如果已經移除任務,則返回 true
public void purge()
    嘗試從工作隊列移除所有已取消的 Future 任務。此方法可用作存儲回收操作,它對功能沒有任何影響。
    取消的任務不會再次執行,但是它們可能在工作隊列中累積,直到worker線程主動將其移除。
    調用此方法將試圖立即移除它們。但是,如果出現其他線程的干預,那麼此方法移除任務將失敗。
當然它還實現了的ExecutorServicesubmit系列接口
abstract <T> Future<T>submit(Runnable task, T result)
Submits a Runnable task for execution and returns a Future representing that task.
如果執行成功就返回T result
abstract <T> Future<T>submit(Callable<T> task)
Submits a value-returning task for execution and returns a Future representing the pending results of the task.
abstract Future<?>submit(Runnable task)
Submits a Runnable task for execution and returns a Future representing that task.

原文地址: http://blog.csdn.net/linghu_java/article/details/17123057


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章