线程池 浅析

本文是对java线程池的粗浅分析,视野局限于线程池的基本实现,不包含生命周期,状态管理。

 

线程池的特点是将任务的提交和执行分开。这样做的好处是,能使处理器尽量多地同时执行任务。

 

为此,线程池提供了两个角色:

任务 task

执行任务的工人 worker

 

与此相关,需要考虑:

工人的数量

工人数量的考量是线程池设计的一个关键。因此,这一点由构造线程池时,提供的头两个参数决定。

最小雇佣数量 corePoolSize

最多工人数量 maximumPoolSize

 

何时解雇多余 最小雇佣数量 的工人

工人多余任务时,它们会等待任务的到来,如果规定时间内,还没有任务,那我们就解雇多余的工人。

这个规定的时间就是构造子里的第三,第四个参数。

 

能接受的任务数量

一个工人,某一时间只能处理一个任务。工人的数量是有限的,因此多余工人数量的任务来了时:

线程池就要考虑是否接受

Y:

处于等待中的任务堆积到多少就不再允许接受任务

定等待 任务列表的容量[bound],达到容量后不再接受新任务。

无限制地接受等待任务[unbound]

设置何种任务等待列表由构造子的第五个参数决定。

 

N:

以何种方式拒绝:

由构造子的第七个参数决定。

 

第六个参数决定了

工人手里执行任务线程的工厂方法。

 

 

工作原理:

 

1.当工人数量没有达到最小雇佣数量时,每当任务来临,线程池都要创建一个工人,然后从线程工厂里创建一个新的线程,把任务作为该线程的target,把线程交给工人,把工人加入工人集合。该任务随即被执行。

 

2.如果任务来临时,当前工人数量poolSize已经大于最小雇佣数量,表明工人已经雇佣的差不多了,先让任务等待吧。

线程池尝试把任务加入任务列表,如果成功,任务提交的步骤就结束了。

 

2.5.任务列表是并发阻塞队列,工人会不断地尝试从队列里获取任务,如果获取到任务(请看5),工人就把任务拿去执行。这是任务的执行步骤。

 

3.如果加入队列失败,说明任务列表已经满了,不能再往里塞任务了。

这时,线程池判断工人数量是否达到最多工人数量。

如果还没有,则决定再雇佣一个工人(这和开始雇佣工人的步骤没有两样)。

 

4.如果已经达到雇佣上线,线程池没有办法了,只好拒绝该任务。

拒绝的方式有:

1、抛出异常给任务递送者,告诉他“老子累屁了,老子真的不干了”。 --这太粗暴了。线程池默认就这么干!

2、偷蔫儿地丢弃这个任务。 --这太猥琐了。

3、从任务列表里丢弃一个最近的任务,然后把这个任务放里。--这太势利眼了。

4、还给任务递送者,让他自己干。--这太无耻了。

 

5.线程池让工人等待任务的策略分两种(本文不考虑生命周期和状态):

死等!当工人数量少于或者等于最低雇佣数量时,它们没啥任务干了,就必须死等。

如果在给定时间内,没有任务来到,线程池开始数人头,如果不多于最低雇佣数量,这个工人还得重新等一个给定时间那么长。

 

6.否则,线程池把该工人的线程结束,告诉当前等待的工人,你没有任务了。不要再等了。

 

7.没有拿到任务的工人,被清除出工人集合--该工人正式下岗。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值