入门介绍
一、线程池的两个核心队列
- 线程等待池,即线程队列BlockingQueue。
- 任务处理池(PoolWorker),即正在工作的Thread列表(HashSet<Worker>)。
二、 关键参数
- int corePoolSize:核心池大小,这个参数跟后面讲的线程池原理有很大的关系。在创建了线程池之后,默认情况下,线程池中并没有任何线程,而是等待所有的任务到来之时才进行创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法 ,从这个两个方法的名字可以知道是预创建线程的意思,即在没有任务来临之前先创建好corePoolSize个线程或者一个线程。默认情况下,在创建好线程池之后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数量达到corePoolSize后,就会把达到的任务放到缓存队列中去。
- int maximumPoolSize:线程池最大线程数量,这是个非常重要的参数,它表示在线程池中最多能创建线程的数量;在corePoolSize和maximumPoolSize的线程数会被自动释放,而小于corePoolSize的则不会。
- long keepAliveTime:表示线程没有执行任务时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会生效,直到线程池数量不大于corePoolSize,即只有当线程池数量大于corePoolSize数量,超出这个数量的线程一旦到达keepAliveTime就会终止。但是如果调用了allowCoreThreadTimeout(boolean)方法,即使线程池的线程数量不大于corePoolSize,线程也会在keepAliveTime之后就终止,知道线程池的数量为0为止。
- TimeUnit unit:参数keepAliveTime的时间单位,一个时间单位枚举类。
- BlockingQueue workQueue:一个阻塞队列,用来存储等待执行任务的队列,这个参数选择也很重要,会对线程池的运行过程产生重大影响,一般来说,这里的阻塞队列就是(ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue;)。
- ArrayBlockingQueue, 是一个基于数组结构的游街阻塞队列, 此队列按FIFO(先进先出)原则对元素进行排序。
- LinkedBlockingQueue, 一个基于链表结构的阻塞队列,此队列按FIFO(先进先出)原则对元素进行排序, 吞吐量通常要高于ArrayBlockingQueue. 静态工厂方法Executors.newFixedThreadPool使用了这个队列。
- SynchronousQueue, 一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态, 吞吐量通常要高于LinkedBlockingQueue。静态工厂方法Executors.newCacheThreadPool使用
- ThreadFactory ThreadFactory:线程工厂,主要用来创建线程;可以是一个自定义的线程工厂,默认就是Executors.defaultThreadFactory()。用来在线程池中创建线程。
- RejectedExecutionHandler handler:表示当拒绝处理任务时的策略,也是可以自定义的,默认是我们前面的4种取值:
- ThreadPoolExecutor.AbortPolicy(默认的,一言不合即抛异常的)
- ThreadPoolExecutor.DiscardPolicy(一言不合就丢弃任务)
- ThreadPoolExecutor.DiscardOldestPolicy(一言不合就把最前面(最近)的任务给抛弃,然后尝试执行当前任务(重复此过程))
- ThreadPoolExecutor.CallerRunsPolicy(由调用者所在线程来执行任务)
三、线程池状态