JAVA线程池的工作流程是怎么样的?

1 当一个任务通过submit或者execute方法提交到线程池的时候,如果当前池中线程数(包括闲置线程)小于coolPoolSize,则创建一个线程执行该任务。

2 如果当前池中线程数大于等于coolPoolSize,则将该任务加入到等待队列。

3 如果任务不能入队,说明等待队列已满,若当前池中线程数小于maximumPoolSize,则创建一个临时线程(非核心线程)执行该任务。

4 如果当前池中线程数已经等于maximumPoolSize,此时无法执行该任务,根据拒绝执行策略处理,后面还会详细讲解具体的拒绝执行策略。

注意:当池中线程数大于coolPoolSize,超过keepAliveTime时间的闲置线程会被回收掉。回收的是非核心线程,核心线程一般是不会回收的。如果设置allowCoreThreadTimeOut(true),则核心线程在闲置keepAliveTime时间后也会被回收。

任务队列是一个阻塞队列,线程执行完任务后会去队列取任务来执行,如果队列为空,线程就会阻塞,直到取到任务。

我们假定有这个场景:

corePoolSize:1
mamximumPoolSize:3
keepAliveTime:60s
workQueue:ArrayBlockingQueue,有界阻塞队列,队列大小是4
handler:默认的策略,抛出来一个ThreadPoolRejectException

以下是新任务来时的场景:以poolSize=0 表示线程数量

1.来了一个任务,poolSize<corePoolSize 新建一个线程
2.又来了一个任务,poolSize>=corePoolSize ,队列未满,将任务丢入队列等待执行
3.继续添加任务,如果队列满了,而 poolSize < maximum,此时将会新建线程
4.如果继续添加任务,队列满,线程数量达到maximum,则会让handler 去处理。默认抛出异常
5.如果现在线程数量是3,但是都处于空闲状态,空闲超过60s 之后,其中2个线程就会被回收,保留一个(coolPoolSize=1)

所以当任务来临时的处理顺序是这样的:

首先创建 corePoolSize 线程
然后丢到队列等待
队列满,新建maximum线程
继续满,handler 处理

猜你喜欢

转载自www.cnblogs.com/gaopengpy/p/12149060.html
今日推荐