前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java线程池---ThreadPoolExecutor解析

Java线程池---ThreadPoolExecutor解析

作者头像
None_Ling
发布2018-10-24 15:05:00
4910
发布2018-10-24 15:05:00
举报
文章被收录于专栏:Android相关Android相关

ThreadPoolExecutor属性介绍

ThreadPoolExecutor中的ctl变量中已经解释了线程池中ctl变量中,高3位代表线程池当前的状态,而低28位表示线程池中线程的总数。

ThreadPoolExecutor执行任务

而了解了线程池ctl变量的意义后,在线程池中,会调用execute函数来执行任务,在execute函数解析中,可以看到线程池在有任务需要被执行的时候会判断:

  1. 核心线程未达到corePoolSize的时候,会将被执行的任务作为firstTask,并且新起Worker创建Thread执行任务。
  2. 如果超过了核心线程,则会判断当前线程池是否正处于Running状态,如果处于的话,那么则将Task插入到队列中
  3. 如果插入队列成功的话,那么会重新再检查一次当前状态,如果当前状态在其他线程改成了非Running的话,那么则需要从队列中把刚加入的Task remove掉,如果从队列Remove成功了,那么就会执行Reject拒绝策略。
  4. 如果remove失败,或者处于Running状态的话,那么就会判断,当前的Worker是否为0,如果为0的话,那么就会以非核心线程的方式,去执行这个Task
  5. 如果当前线程没有处于Running状态,或者插入队列失败的话,那么就会尝试以当前Task作为firstTask,非核心线程的方式添加Worker执行这个任务,如果添加Worker失败了的话,那么就会执行Reject策略。

ThreadPoolExecutor添加线程

而在AddWorker方法中,会返回是否成功创建Worker

  1. 判断线程池当前状态,如果比SHUTDOWN状态要大的话,那么直接返回false,如果是SHUTDOWN的话,那么只会判断当前任务队列中是否还有任务,而新添加的任务则不会管,如果队列中还有任务的话,那么就会在线程池停止运行前,将队列中剩余的任务执行完。
  2. 检查当前WorkerCount是否合法,如果不合法,即判断是否是核心线程,如果是的话,那么判断WorkerCount是否大于corePoolSize,如果不是核心线程的话,那么则判断WorkerCount是否大于maximumPoolSize,如果不合法的话,那么直接返回false。
  3. 如果满足了线程池大小要求,那么就会尝试通过CAS操作增加WorkerCount,如果CAS操作失败了的话,那么就重新检查当前线程池状态。
  4. 如果CAS增加线程总数成功的话,那么就会创建一个Worker对象,然后再检查一次线程池当前状态,如果当前状态大于SHUTDOWN,或者是SHUTDOWN但是firstTask不为空的时候,才会调用decrementWorkerCount减少WorkerCount,并且返回false。
  5. 如果正常运转的话,那么就会将新创建的Worker添加到WorkerSet中,并且启动Thread,返回true。

ThreadPoolExecutor中各个线程处理任务

在线程启动后,会执行runWorker方法,会循环获取Task,然后执行Task中的run方法。

  1. 首先设置completedAbruptly为true,表示Worker在执行任务的时候异常退出了。后面如果任务全部执行完了,没有异常的话,那么就会将completedAbruptly设置成false。
  2. 判断firstTask是否存在,如果存在则执行,如果不存在的话,那么则获取任务队列中的Task,然后准备开始执行
  3. 在执行之前会调用beforeExecute来告知子类,任务即将被开始执行
  4. 接着执行任务,无论执行任务的过程中,是否出现异常,都会执行afterExecute方法告知子类,任务执行完毕,而在该方法中,如果出现异常,则会将异常通过参数的方式,告知子类,在执行该任务的过程中,发生了某个异常。一旦出现异常,线程会立马终止。
  5. 如果所有任务执行完后,没有出现异常,则会将completedAbruptly设置成false

ThreadPoolExecutor中Worker任务处理完成后退出

在Worker执行完所有任务或者在执行任务的时候发生了异常,会处理工作线程退出,来判断在当前Worker执行完任务之后,是否还需要再重新启动一个新的Worker来处理新任务。

  1. 判断是否是异常中断,如果是异常中断的话,则需要将WorkerCount减一
  2. 将Worker从WorkerSet中移除
  3. 调用tryTerminate,尝试终止线程池
  4. 判断线程池当前状态是否小于STOP,如果是的话,那么则判断是否是异常终止的,如果是异常终止的Worker,则直接调用addWorker,看是否还需要添加新的Worker去处理剩余的Task
  5. 如果不是异常终止的,那么则判断当前还需要多少个Worker来处理任务,如果当前的Worker总数超过了最少要的Worker总数的话,就直接返回了,因为有足够多的Worker可以处理Task,如果Worker不够的话,那么就调用addWorker尝试添加新的Worker去处理任务。

ThreadPoolExecutor退出

终止线程池的方法有两个ShutDown以及ShutDownNow,调用完之后,线程池就开始进入关闭的状态了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.06.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ThreadPoolExecutor属性介绍
  • ThreadPoolExecutor执行任务
  • ThreadPoolExecutor添加线程
  • ThreadPoolExecutor中各个线程处理任务
  • ThreadPoolExecutor中Worker任务处理完成后退出
  • ThreadPoolExecutor退出
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档