分析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,线程也会被终止。

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