源码剖析 ThreadPoolExecutor 线程池及阻塞队列

本文章对ThreadPoolExecutor线程池的底层源码进行分析,线程池如何起到了线程复用、又是如何进行维护我们的线程任务的呢?我们直接进入正题:

首先我们看一下ThreadPoolExecutor类的源码

 1 public ThreadPoolExecutor(int corePoolSize,
 2                               int maximumPoolSize,
 3                               long keepAliveTime,
 4                               TimeUnit unit,
 5                               BlockingQueue<Runnable> workQueue, 
 6                               ThreadFactory threadFactory,
 7                               RejectedExecutionHandler handler) {
    //拒绝策略
 8         if (corePoolSize < 0 ||
 9             maximumPoolSize <= 0 ||
10             maximumPoolSize < corePoolSize ||
11             keepAliveTime < 0)
12             throw new IllegalArgumentException();
13         if (workQueue == null || threadFactory == null || handler == null)
14             throw new NullPointerException();
15         this.acc = System.getSecurityManager() == null ?
16                 null :
17                 AccessController.getContext();
18         //核心线程
19         this.corePoolSize = corePoolSize;
20         //最大线程数
21         this.maximumPoolSize = maximumPoolSize;
22         //阻塞队列,即今天主题
23         this.workQueue = workQueue;
24         //超时时间
25         this.keepAliveTime = unit.toNanos(keepAliveTime);
26         this.threadFactory = threadFactory;
27         //拒绝策略
28         this.handler = handler;
29     } 

这是我们线程池实例化的时候的参数,其实最大的实用性来说,就是核心线程与最大线程数的设定,这个完全靠个人经验,并没有一个真正意义上的公式可以适用所有的业务场景。
  
  我们的线程池初始化好后,我们自己会调用excute方法来让线程池运行我们的线程任务,那我们就先来看看这个方法的实现:

 1 public void execute(Runnable command) {
   
 2         if (command == null)
 3             throw new NullPointerException();
 4         /*
 5          * 第一步:工作线程是否小于核心线程数量,如果是添加work中,worker其实也是一个线程,只不过它内部操作的是我们的上传的任务
 6          * 第二步:如果大于核心线程数量,添加到worker队列中,每一个不同的队列offer的实现方法也是不一样的,今天我们主要探讨这个
 7          * 第三步:阻塞队列被塞满了,需要创建新的非核心线程数量worker线程去处理我们的任务,创建worker线程失败了会触发拒绝策略,默认抛异常
 8          */
 9         int c = ctl.get();
10         if (workerCountOf(c) < corePoolSize) {
   
11             if (addWorker(command, true))
12                 return;
13             c = ctl.get();
14         }
15         if (isRunning(c) && workQueue.offer(command)) {
   
16             int recheck = ctl.get();
17             if (! isRunning(recheck) && remove(command))
18                 reject(command);
19             else if (workerCountOf(recheck) == 0)
20                 addWorker(null, false);
21         }
22         else if (!addWorker(command, false))
23             reject(command);
24     }
25 

我们看到当任务调用的时候,会执行addworker,那么worker是个什么东西呢?我们来看看它的构造实例:我们看一下worker类,就发现其实worker也是一个线程

 1 private final class Worker
 2         extends AbstractQueuedSynchronizer
 3         implements Runnable
 4     {
   
 5     
 6     ......
 7     
 8     Worker(Runnable firstTask) {
   
 9             setState(-1); // inhibit interrupts until runWorker
10             this.firstTask = firstTask;
11             this.thread = getThreadFactory().newThread(this);
12         }
13 
14         /** 覆盖执行run方法
15           */
16         public void run() {
   
17             runWorker(this);
18         }
19     ......
20     
21     } 

这次我们来看一下addworker是怎么操作的:

 1 private boolean addWorker(Runnable firstTask, boolean core) {
   
 2         retry:
 3         for (;;) {
   
 4             int c = ctl.get();
 5             int rs = runStateOf(c);
 6 
 7             // Check if queue empty only if necessary.
 8             if (rs >= SHUTDOWN &&
 9                 ! (rs == SHUTDOWN &&
10                    firstTask == null &&
11                    ! workQueue.isEmpty()))
12                 return false;
13 
14             for (;;) {
   
15                 int wc = workerCountOf(c);
16                 if (wc >= CAPACITY ||
17                     //不允许创建大于最大核心线程数的任务
18                     wc >= (core ? corePoolSize : maximumPoolSize))
19                     return false<
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图灵课堂诸葛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值