美文网首页
1203-AsyncTask详解一:线程池的基本设置

1203-AsyncTask详解一:线程池的基本设置

作者: 方衍 | 来源:发表于2016-12-04 22:01 被阅读31次

    AsyncTask的内部使用线程池处理并发,要了解它是怎样使用线程池的,那要先了解线程池的基本设置

    线程池的基本参数

        public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler) {
            // ......
        }
    
    • corePoolSize: 核心线程数目,即使线程池没有任务,核心线程也不会终止(除非设置了allowCoreThreadTimeOut参数),可以理解为“常驻线程”
    • maximumPoolSize: 线程池中允许的最大线程数目;一般来说,线程越多,线程调度开销越大;因此一般都有这个限制
    • keepAliveTime: 当线程池中的线程数目比核心线程多的时候,如果超过这个keepAliveTime的时间,多余的线程会被回收;这些与核心线程相对的线程通常被称为缓存线程
    • unit: keepAliveTime的时间单位
    • workQueue: 任务执行前保存任务的队列;这个队列仅保存由execute提交的Runnable任务
    • threadFactory: 用来构造线程池的工厂;一般都是使用默认的
    • handler: 当线程池由于线程数目和队列限制而导致后续任务阻塞的时候,线程池的处理方式。

    线程池如何调度线程

    当一个新的任务来时,线程池是如何调度线程的?

    1. 如果线程池中线程的数目少于corePoolSize,就算线程池中有其他的没事做的核心线程,线程池还是会重新创建一个核心线程;直到核心线程数目到达corePoolSize(常驻线程就位)
    2. 如果线程池中线程的数目大于或者等于corePoolSize,但是工作队列workQueue没有满,那么新的任务会放在队列workQueue中,按照FIFO的原则依次等待执行;(当有核心线程处理完任务空闲出来后,会检查这个工作队列然后取出任务去执行)
    3. 如果线程池中线程数目大于等于corePoolSize,并且工作队列workQueue满了,但是总线程数目小于maximumPoolSize,那么直接创建一个线程处理被添加的任务。
    4. 如果工作队列满了,并且线程池中线程的数目到达了最大数目maximumPoolSize,那么就会用最后一个构造参数handler处理;默认的处理方式是直接拒绝任务,然后抛出一个异常

    总结起来说,当有新的任务要处理时,先看线程池中的线程数量是否大于 corePoolSize,再看缓冲队列 workQueue 是否满,最后看线程池中的线程数量是否大于 maximumPoolSize。另外,当线程池中的线程数量大于 corePoolSize 时,如果里面有线程的空闲时间超过了 keepAliveTime,就将其移除线程池,这样,可以动态地调整线程池中线程的数量。

    相关文章

      网友评论

          本文标题:1203-AsyncTask详解一:线程池的基本设置

          本文链接:https://www.haomeiwen.com/subject/ckxkmttx.html