ThreadPoolExecutor線程池的實例和詳解

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TThradPoolExecutor
{
    public static void main(String[] args)
    {
        /**
         * 1、corePoolSize核心線程數大小,當線程數<corePoolSize ,會創建線程執行runnable
         * 2、maximumPoolSize 最大線程數, 當線程數 >= corePoolSize的時候,會把runnable放入workQueue中
         * 3、keepAliveTime  保持存活時間,當線程數大於corePoolSize的空閒線程能保持的最大時間。
         * 4、unit 時間單位
         * 5、workQueue 保存任務的阻塞隊列
         * 6、threadFactory 創建線程的工廠
         * 7、handler 拒絕策略
         * handler 拒絕策略:rejectedExecutionHandler
         * 線程池任務隊列超過最大值之後的拒絕策略,RejectedExecutionHandler 是一個接口,裏面只有一個 
         * rejectedExecution 方法,可在此方法內添加任務超出最大值的事件處理。ThreadPoolExecutor 也提供了 4 
         * 種默認的拒絕策略:
         *
         * new ThreadPoolExecutor.DiscardPolicy():丟棄掉該任務,不進行處理
         * new ThreadPoolExecutor.DiscardOldestPolicy():丟棄隊列裏最近的一個任務,並執行當前任務
         * new ThreadPoolExecutor.AbortPolicy():直接拋出 RejectedExecutionException 異常
         * new ThreadPoolExecutor.CallerRunsPolicy():既不拋棄任務也不拋出異常,直接使用主線程來執行此任務
         */
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 10, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue(100));
        /**
         * ThreadPoolExecutor提交任務的兩種方法:
         * 無返回值異步調用:execute()方法,底層使用Runnable的run()
         * 有返回值異步調用:submit()方法,底層使用Callable的call()
         */
        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                // 執行線程池
                System.out.println("Hello, Java.");
            }
        });


    }
}

線程池關閉,可以使用 shutdown() 或 shutdownNow() 方法,它們的區別是:
shutdown():不會立即終止線程池,而是要等所有任務隊列中的任務都執行完後纔會終止。執行完 shutdown 方法之後,線程池就不會再接受新任務了。
shutdownNow():執行該方法,線程池的狀態立刻變成 STOP 狀態,並試圖停止所有正在執行的線程,不再處理還在池隊列中等待的任務,執行此方法會返回未執行的任務。

但很多文章都說shutdownNow()會中斷當前的任務,容易被誤解爲當前任務直接停止,實則不然。

注意“中斷”的英文是“interrupt”,在java裏指的是對線程發起interrupt()請求,interrupt()方法的作用可以去百度一下,並不會殺掉線程,只是中斷線程的阻塞狀態,例如中斷線程的sleep()方法使線程不再睡眠。

如果你的程序中沒有會拋出InterruptedException異常的方法,或者將會拋出InterruptedException()的方法進行try/catch,捕獲到InterruptedException時只是打印日誌並繼續執行,那麼當前任務將會執行到完成爲止。

所以如果希望將當前任務也丟棄,用如下代碼。

executorService.shutdown();
try {
    executorService..awaitTermination(1, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
    e.printStackTrace();
}

 

 

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