分析java.uitl.concurrent.ThreadPoolExecutor

1. java.uitl.concurrent.ThreadPoolExecutor類是線程池中最核心的一個類,因此如果要透徹地瞭解Java中的線程池,必須先了解這個類。下面我們來看一下ThreadPoolExecutor類的具體實現源碼。

    在ThreadPoolExecutor類中提供了四個構造方法:
    public class ThreadPoolExecutor extends AbstractExecutorService {
    .....
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
        BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
    ...
    }
    
2. 以上構造器中各個參數的含義:
   2.1 corePoolSize :代表該線程中允許的核心線程數,要和工作的線程數量區分開來,兩者不 
                      等價(工作的線程數量一定不大於corePoolSize,即當超過後,會將線程
                      放入隊列中),可以理解爲一個ArrayList集合中,默認空間是10,但存放的 
                      元素的數量 不一定是10, 在這裏這個10就寓指corePoolSize ,存放元
                      素的個數是工作線程數量 
   2.2 maximumPoolSize :這個參數的意思就是該線程池所允許的最大線程數量
   2.3 keepAliveTime :即當線程池中的線程數大於corePoolSize時,如果一個線程空閒的時間達到keepAliveTime,則會終止,直到線程池中的線程數不超過corePoolSize。
        但是如果調用了allowCoreThreadTimeOut(boolean)方法,在線程池中的線程數不大於corePoolSize時,keepAliveTime參數也會起作用,直到線程池中的線程數爲0
   2.4 unit :時間單位
        TimeUnit.DAYS;               //天
        TimeUnit.HOURS;             //小時
        TimeUnit.MINUTES;           //分鐘
        TimeUnit.SECONDS;           //秒
        TimeUnit.MILLISECONDS;      //毫秒
        TimeUnit.MICROSECONDS;      //微妙
        TimeUnit.NANOSECONDS;       //納秒
   2.5 workQueue :阻塞隊列,在此作用就是用來存放線程。一個阻塞隊列,用來存儲等待執行的任務,這個參數的選擇也很重要,會對線程池的運行過程產生重大影響,一般來說,這裏的阻塞隊列有以下幾種選擇
        ArrayBlockingQueue; 基於數組的先進先出隊列,此隊列創建時必須指定大小;
        LinkedBlockingQueue; 基於鏈表的先進先出隊列,如果創建時沒有指定此隊列大小,則默認爲Integer.MAX_VALUE;
        SynchronousQueue; 這個隊列比較特殊,它不會保存提交的任務,而是將直接新建一個線程來執行新來的任務。
        ArrayBlockingQueue和PriorityBlockingQueue使用較少,一般使用LinkedBlockingQueue和Synchronous。線程池的排隊策略與BlockingQueue有關
   2.6 threadFactory :線程工廠,主要用來創建線程
   2.7 defaultHandler :由於超出線程數量和隊列容量而對繼續增加的任務進行處理的程序,表示當拒絕處理任務時的策略,有以下四種取值:
        ThreadPoolExecutor.AbortPolicy:丟棄任務並拋出RejectedExecutionException異常。 
        ThreadPoolExecutor.DiscardPolicy:也是丟棄任務,但是不拋出異常。 
        ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊列最前面的任務,然後重新嘗試執行任務(重複此過程)
        ThreadPoolExecutor.CallerRunsPolicy:由調用線程處理該任務 
        
3. 任務提交給線程池之後到被執行的整個過程,下面總結一下:
   3.1 如果當前線程池中的線程數目小於corePoolSize,則每來一個任務,就會創建一個線程去執行這個任務;
   3.2 如果當前線程池中的線程數目>=corePoolSize,則每來一個任務,會嘗試將其添加到任務緩存隊列當中,若添加成功,則該任務會等待空閒線程將其取出去執行;若添加失敗(一般來說是任務緩存隊列已滿),則會嘗試創建新的線程去執行這個任務;
   3.3 如果當前線程池中的線程數目達到maximumPoolSize,則會採取任務拒絕策略進行處理;
   3.4 如果線程池中的線程數量大於 corePoolSize時,如果某線程空閒時間超過keepAliveTime,線程將被終止,直至線程池中的線程數目不大於corePoolSize;如果允許爲核心池中的線程設置存活時間,那麼核心池中的線程空閒時間超過keepAliveTime,線程也會被終止。

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