- 核心线程数、最大线程数、阻塞队列、线程最大存活时间
corePoolSize 线程池核心线程大小
maximumPoolSize 线程池最大线程数量
keepAliveTime 空闲线程存活时间
unit 空间线程存活时间单位
workQueue 工作队列
新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。jdk中提供了四种工作队列
threadFactory 线程工厂
创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等
handler 拒绝策略
当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢。这里的拒绝策略,就是解决这个问题的
-
线程池工作流程
1 当一个任务通过 submit或者execute方法提交到线程池的时候,如果当前池中线程数(包括闲置线程)小于coolPoolSize,则创建一个线程执行该任务。2 如果当前线程池中线程数已经达到coolPoolSize,则将任务放入等待队列。3 如果任务不能入队,说明等待队列已满,若当前池中线程数小于maximumPoolSize,则创建一个临时线程(非核心线程)执行该任务。4 如果当前池中线程数已经等于maximumPoolSize,此时无法执行该任务,根据拒绝执行策略处理。注意:当池中线程数大于coolPoolSize,超过keepAliveTime时间的闲置线程会被回收掉。回收的是非核心线程,核心线程一般是不会回收的。如果设置allowCoreThreadTimeOut(true),则核心线程在闲置keepAliveTime时间后也会被回收。任务队列是一个阻塞队列,线程执行完任务后会去队列取任务来执行,如果队列为空,线程就会阻塞,直到取到任务。我们假定有这个场景:corePoolSize:1mamximumPoolSize:3keepAliveTime:60sworkQueue:ArrayBlockingQueue,有界阻塞队列,队列大小是4handler:默认的策略,抛出来一个ThreadPoolRejectException以下是新任务来时的场景:以poolSize=0 表示线程数量1.来了一个任务,poolSize<corePoolSize 新建一个线程2.又来了一个任务,poolSize>=corePoolSize ,队列未满,将任务丢入队列等待执行3.继续添加任务,如果队列满了,而 poolSize < maximum,此时将会新建线程4.如果继续添加任务,队列满,线程数量达到maximum,则会让handler 去处理。 默认抛出异常5.如果现在线程数量是3,但是都处于空闲状态,空闲超过60s 之后,其中2个线程就会被回收,保留一个(coolPoolSize=1)所以当任务来临时的处理顺序是这样的:首先创建 corePoolSize 线程然后丢到队列等待队列满,新建maximum线程继续满,handler 处理 - 线程池的类别和区别
- 阻塞队列的类别和区别
1.什么是阻塞队列
我们知道,PriorityQueue、LinkedList这些都是非阻塞队列。在我们使用非阻塞队列的时候有一个很大问题,它不会对当前线程产生阻塞,那么在面对类似消费者-生产者的模型时,就必须额外地实现同步策略以及线程间唤醒策略,这个实现起来就非常麻烦。但是有了阻塞队列就不一样了,它会对当前线程产生阻塞,比如一个线程从一个空的阻塞队列中取元素,此时线程会被阻塞直到阻塞队列中有了元素。当队列中有元素后,被阻塞的线程会自动被唤醒(不需要我们编写代码去唤醒)。这样提供了极大的方便性。
2.阻塞队列的种类
阻塞队列本质上就是队列,它主要有一下几种:
ArrayBlockingQueue:基于数组实现的阻塞队列,先进先出队列,有界队列。在创建时必须制定容量大小。并可以指定公平性与非公平性,默认情况下是非公平的,即不保证等待时间最长的队列最优先能够访问队列。
LinkedBlockingQueue:基于链表实现的阻塞队列,先进先出队列,有界队列。在创建时如果不指定容量大小,则默认大小为Integer.MAX_VALUE。
PriorityBlockingQueue:按照元素的优先级对元素进行排序,按照优先级顺序出队。并且该阻塞队列为无界阻塞队列,即容量没有上限(源码中它没有容器满的信号标志)。
DelayQueue:基于PriorityQueue的延时阻塞队列,无界队列。DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素。因为DelayQueue是一个无界队列,所以往队列中插入数据的操作永远不会被阻塞,而只有获取数据的操作才会被阻塞。
SynchronousQueue:一个不存储元素的阻塞队列。
LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
3.阻塞队列中的几个主要方法
put方法用来向队尾存入元素,如果队列满,则等待;
take方法用来从队首取元素,如果队列为空,则等待;
offer方法用来向队尾存入元素,如果队列满,则等待一定的时间,当时间期限达到时,如果还没有插入成功,则返回false;否则返回true;
poll方法用来从队首取元素,如果队列空,则等待一定的时间,当时间期限达到时,如果取到,则返回null;否则返回取得的元素;