1. 程式人生 > >ThreadPoolExecutor裡面4種拒絕策略

ThreadPoolExecutor裡面4種拒絕策略

threadPoolExecutor類實現了ExecutorService介面和Executor介面,可以設定執行緒池corePoolSize,最大執行緒池大小,AliveTime,拒絕策略等。常用構造方法:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,

long keepAliveTime, TimeUnit unit,

BlockingQueue<Runnable> workQueue,

RejectedExecutionHandler handler)

corePoolSize: 執行緒池維護執行緒的最少數量

maximumPoolSize:執行緒池維護執行緒的最大數量

keepAliveTime: 執行緒池維護執行緒所允許的空閒時間

unit: 執行緒池維護執行緒所允許的空閒時間的單位

workQueue: 執行緒池所使用的緩衝佇列

handler: 執行緒池對拒絕任務的處理策略

當一個任務通過execute(Runnable)方法欲新增到執行緒池時:

l  如果此時執行緒池中的數量小於corePoolSize,即使執行緒池中的執行緒都處於空閒狀態,也要建立新的執行緒來處理被新增的任務。

2  如果此時執行緒池中的數量等於 corePoolSize,但是緩衝佇列 workQueue未滿,那麼任務被放入緩衝佇列。

3  如果此時執行緒池中的數量大於corePoolSize,緩衝佇列workQueue滿,並且執行緒池中的數量小於maximumPoolSize,建新的執行緒來處理被新增的任務。

4  如果此時執行緒池中的數量大於corePoolSize,緩衝佇列workQueue滿,並且執行緒池中的數量等於maximumPoolSize,那麼通過 handler所指定的策略來處理此任務。也就是:處理任務的優先順序為:核心執行緒corePoolSize、任務佇列workQueue、最大執行緒maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。  

當執行緒池中的執行緒數量大於 corePoolSize時,如果某執行緒空閒時間超過keepAliveTime,執行緒將被終止。這樣,執行緒池可以動態的調整池中的執行緒數。  

JDK內建了四種拒絕策略:

1、AbortPolicy策略

該策略直接丟擲異常,阻止系統工作

2、CallerRunsPolicy策略

只要執行緒池未關閉,該策略直接在呼叫者執行緒中運行當前被丟棄的任務。顯然這樣不會真的丟棄任務,但是,呼叫者執行緒效能可能急劇下降。

3、DiscardOledestPolicy策略

丟棄最老的一個請求任務,也就是丟棄一個即將被執行的任務,並嘗試再次提交當前任務。

4、DiscardPolicy策略

默默的丟棄無法處理的任務,不予任何處理。

擴充套件RejectedExecutioHandler介面,自定義拒絕策略

先看下RejectedExecutionHandler介面吧:

public interfaceRejectedExecutionHandler{

    voidrejectedExecution(Runnable r,ThreadPoolExecutor executor);

}

再舉個例子吧:

public classTestRejectHandler {

    class MyTask implements Runnable{

       @Override

       public void run() {

           System.out.println("Thread ID:"+Thread.currentThread().getId());

           try{

              Thread.sleep(1000);

           }catch(InterruptedException e){

              e.printStackTrace();

           }

       }

    }

    public void test(){

       ThreadPoolExecutor executor= newThreadPoolExecutor(5, 5,

              0L, TimeUnit.MILLISECONDS,

              newLinkedBlockingQueue(10),

              Executors.defaultThreadFactory(),

              newRejectedExecutionHandler() {  

                  @Override

                  public voidrejectedExecution(Runnable r, ThreadPoolExecutor executor) {

                     System.out.println(r.toString()+" 被拋棄了");

                  }

              });

       MyTask task= newMyTask();

       for(int i=0;i<20;i++){

           executor.submit(task);

       }

       executor.shutdown();

    }

 

}