天天看點

Java.util.concurrent之 Executor架構與線程池

Executor架構是java 5 中引入的,内部使用了線程池機制。Executor架構包括:Executor, ExecutorService,Executors,ThreadPoolExecutor等。

Executor ——接口

public interface Executor {
  void execute (Runnable command);
}
           

Executor接口中定義一個方法execute(Runnable command),該方法接收一個Runnable執行個體,它用來執行一個任務,任務即是一個實作了Runnable接口的類。

ExecutorService——接口

public interface ExecutorService extends Executor {
  void shutdown();
  List<Runnable> shutdownNow();
  boolean isShutdown();
  boolean isTerminated();
  boolean awaitTermination(long timeout, TimeUnit unit)
    throw InterruptedException;
  //...其他用于送出的便利方法
}
           

ExecutorService繼承了Executor的接口,同時提供了更豐富的生命周期管理的方法。ExecutorService的生命周期有3種狀态:運作、關閉和已停止。

shutdown方法将執行平緩的關閉過程:不再接受新的任務,同時等待已經送出的任務執行完成——包括哪些還未開始執行的任務。

shutdownNow方法将執行粗暴的關閉過程:它将嘗試取消所有運作中的任務,并且不再啟動隊列中尚未開始執行的任務。

Executors提供工廠方法用于建立線程池

  • newFixedThreadPool:将建立固定長度的線程池,每送出一個任務就建立一個線程,直到達到線程池的最大數量。(如果某個線程由于發生了未預期的Exception而結束,那麼線程池會補充一個新的線程)。
  • newCachedThreadPool:建立一個可緩存的線程池,如果線程池的目前規模超過了處理需求時,那麼将回收空閑的線程,而當需求增加時,則可以添加新的線程,線程池的規模不存在任何限制。
  • newSingleThreadPool:是一個單線程的Executor,它建立單個工作線程來執行任務,如果這個線程異常結束,會建立另一個線程來替代。newSingleTreadPool能確定依照任務在隊列中的順序來串行執行(例如FIFO、LIFO、優先級)
  • newScheduledThreadPool:建立一個固定長度的線程池,而且以延遲或定時的方式來執行任務。

ThreadPoolExecutor

ThreadPoolExecutor為一些Executor提供了基本的實作,這些Executor是由Executors中newCachedThreadPool、newFixedThreadPool等方法傳回的。ThreadPoolExecutor是一個靈活的、穩定的線程池,允許進行各種定制。

public ThreadPoolExecutor(int corePoolSize,//線程池的基本大小
                          int maximumPoolSize,//最大大小
                          long keepAliveTime,//存活時間
                          Timeout unit,
                          SlockingQueue<Runable> workQueue,
                          ThreadFactory threadFactory,
                          RejectExecutionHandler handler){...}
           

通過調節線程池的基本大小和存活時間,可以幫助線程池回收空閑線程占有的資源。

  • newFixedThreadPool工廠方法将線程池的基本大小和最大大小設定為參數中指定的值,而且建立的線程池不會逾時。
  • newCachedThreadPool工廠方法将線程池的最大大小設定為Integer.MAX_VALUE,而将基本大小設定為零,并将逾時設定為1分鐘,這種方式建立出來的線程池可以無限擴充,并且當需求降低會自動收獲。
//對通過标準工廠方法建立的Executor進行修改
ExecutorService exec = Execoutors.newCachedThreadPool();
if(exec instanceof ThreadPoolExecutor)
  ((ThreadPoolExecutor) exec).setCorePoolSize();
else
  throw new AssertionError(*Oops, bad assumption);