线程池的执行流程

列举一个线程池max=6,core=3,任务队列taskQueue=5;采用饱和策略为1)

则我们看看提交任务给此线程池的执行逻辑如下:

1)首先我们提交第一个任务到线程池,此时核心线程数都还没有用,所以会启动核心线程之一来执行任务

2)接着提交第二个第三个任务到线程池,他们的执行逻辑同第一个任务是一模一样的,线程池会启动核心线程池中剩下的两个线程来执行你新提交的任务

3)接着又有新的任务提交过来,这个时候线程池发现核心线程池中的线程已经都在工作中,所以会去看任务队列taskQueue是否满了,发现并没有,是空的,所以将这个任务放入任务队列中等待核心线程池中有空闲线程时自己来取任务执行

4)接着又提交了4个任务到线程池,他们分别判断核心线程是否空闲,不空闲,然后判断任务队列是否已满,不满,则直接将任务放入队列;

5)接着新的任务又来,则在判断核心线程池和任务队列之后,发现任务依然没有办法处理,(max=6,core=3正在执行任务,新来一个线程,3+1<6,此时队列taskQueue已经满了,corepoolsize=3也都在干活)则会判断是否线程数达到最大,发现没有,则新启动线程来执行任务新的任务开始加入到执行任务中,3个corepoolsize+1个非核心线程,此时执行任务4,可理解新添加的任务是非核心线程任务在执行任务

6)接着又来一个任务,执行流程同5,(此时有5个线程在执行任务,2个非核心线程在执行任务,3个corepoolsize在执行任务);

7)接着又来一个任务,执行流程同5,(此时有6个线程在执行任务,3个非核心线程在执行任务,3个corepoolsize在执行任务);

8)再来一个任务,发现核心线程池在忙,任务队列也满了,线程池中的全部线程也都在工作3个corepoolsize+3个非核心线程=max(6)都在工作,如果加入新的线程则3个corepoolsize+4个非核心线程>max(6),将报拒绝异常,没有办法处理他了,所以他找到了饱和策略,因为饱和策略是默认的抛异常,所以线程池会告诉提交任务的线程,已经没有可以用的线程了。

以上就一个核心线程数是3,总线程数是6,任务队列长度为5,默认策略采用抛异常的策略的从最开始到最后线程池满负荷运作的过程

 

关注点1 线程池大小

线程池有两个线程数的设置,一个为核心池线程数,一个为最大线程数。

在创建了线程池后,默认情况下,线程池中并没有任何线程,等到有任务来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法

当创建的线程数等于 corePoolSize 时,会加入设置的阻塞队列。当队列满时,会创建线程执行任务直到线程池中的数量等于maximumPoolSize。

 

关注点2 适当的阻塞队列

java.lang.IllegalStateException: Queue full

方法 抛出异常 返回特殊值 一直阻塞 超时退出

插入方法 add(e) offer(e) put(e) offer(e,time,unit)

移除方法 remove() poll() take() poll(time,unit)

检查方法 element() peek() 不可用 不可用

 

ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。

LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。

PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。

DelayQueue: 一个使用优先级队列实现的无界阻塞队列。

SynchronousQueue: 一个不存储元素的阻塞队列。

LinkedTransferQueue: 一个由链表结构组成的无界阻塞队列。

LinkedBlockingDeque: 一个由链表结构组成的双向阻塞队列。

 

关注点3 明确拒绝策略

ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。 (默认)

ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。

ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)

ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

 

说明:Executors 各个方法的弊端:

1)newFixedThreadPool 和 newSingleThreadExecutor:

主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至 OOM。

2)newCachedThreadPool 和 newScheduledThreadPool:

主要问题是线程数最大数是 Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至 OOM。

https://blog.csdn.net/qq_33581278/article/details/84568675

都看到这里了,就顺手点击左上角的【关注】按钮,点击右上角的小手,给个评论,关注一下,再走呗!☺

  • 0
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值