Java线程池---processWorkerExit方法解析

/**

  • Performs cleanup and bookkeeping for a dying worker. Called
    • only from worker threads. Unless completedAbruptly is set,
    • assumes that workerCount has already been adjusted to account
    • for exit. This method removes thread from worker set, and
    • possibly terminates the pool or replaces the worker if either
    • it exited due to user task exception or if fewer than
    • corePoolSize workers are running or queue is non-empty but
    • there are no workers.
    • @param w the worker
    • @param completedAbruptly if the worker died due to user exception */

开始清理并且标记一个即将销毁的Worker。只有Worker所在的线程会被调用。除非,completedAbruptly被设置(为true)了,说明当前线程是意外停止了,假设Worker总数已经在退出之前重新调整了的。这个方法把当前Worker线程从WorkerSet中移除,并且如果由于用户Task异常导致退出,或者只有少于corePoolSize的Worker正在运行,或者队列并不是空的但是没有Worker的情况下,可能终止整个线程池,或者重新替换Worker。


 private void processWorkerExit(Worker w, boolean completedAbruptly) {
    if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
        decrementWorkerCount();

    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        completedTaskCount += w.completedTasks;
        workers.remove(w);
    } finally {
        mainLock.unlock();
    }

    tryTerminate();

    int c = ctl.get();
    if (runStateLessThan(c, STOP)) {
        if (!completedAbruptly) {
            int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
            if (min == 0 && ! workQueue.isEmpty())
                min = 1;
            if (workerCountOf(c) >= min)
                return; // replacement not needed
        }
        addWorker(null, false);
    }
}

传入参数: Worker w:要执行退出的Worker对象 boolean completedAbruptly:是否用户异常退出,true为异常退出。

步骤

  1. 判断是否是意外退出的,如果是意外退出的话,那么就需要把WorkerCount--
  2. 加完锁后,同步将completedTaskCount进行增加,表示总共完成的任务数,并且从WorkerSet中将对应的Worker移除
  3. 调用tryTemiate,进行判断当前的线程池是否处于SHUTDOWN状态,判断是否要终止线程
  4. 判断当前的线程池状态,如果当前线程池状态比STOP大的话,就不处理
  5. 判断是否是意外退出,如果不是意外退出的话,那么就会判断最少要保留的核心线程数,如果allowCoreThreadTimeOut被设置为true的话,那么说明核心线程在设置的KeepAliveTime之后,也会被销毁。
  6. 如果最少保留的Worker数为0的话,那么就会判断当前的任务队列是否为空,如果任务队列不为空的话而且线程池没有停止,那么说明至少还需要1个线程继续将任务完成。
  7. 判断当前的Worker是否大于min,也就是说当前的Worker总数大于最少需要的Worker数的话,那么就直接返回,因为剩下的Worker会继续从WorkQueue中获取任务执行。
  8. 如果当前运行的Worker数比当前所需要的Worker数少的话,那么就会调用addWorker,添加新的Worker,也就是新开启线程继续处理任务。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏搜云库

Java 四种线程池的使用

介绍new Thread的弊端及Java四种线程池的使用 1,线程池的作用 线程池作用就是限制系统中执行线程的数量。 根据系统的环境情况,可以自动或手动设置线程...

27290
来自专栏别先生

基于jsp+servlet图书管理系统之后台用户信息删除操作

上一篇的博客写的是修改操作,且附有源码和数据库,这篇博客写的是删除操作,附有从头至尾写的代码(详细的注释)和数据库!   此次删除操作的源码和数据库:http:...

401100
来自专栏李成熙heyli

requirejs 源码简析

requirejs 算是几年前一个比较经典的模块加载方案(AMD的代表)。虽然不曾用过,但它对 webpack, rollup 这些后起之秀有不少借鉴的意义...

342100
来自专栏Java后端技术栈

Java中的锁原理、锁优化、CAS、AQS

Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量。Java语言提供了volatile,在某些...

25840
来自专栏JAVA技术zhai

干货:Java并发编程必懂知识点解析(内附面试题)

26950
来自专栏大学生计算机视觉学习DeepLearning

c++ 网络编程(九)TCP/IP LINUX/windows--使用IOCP模型 多线程超详细教程 以及 多线程实现服务端

原文链接:https://www.cnblogs.com/DOMLX/p/9661012.html

51420
来自专栏程序员宝库

浅谈 Java 并发编程中的若干核心技术

作者:一字马胡 原文:http://www.jianshu.com/p/5f499f8212e7 索引 Java线程 线程模型 Java线程池 Future(...

38290
来自专栏编舟记

Java高编译低运行错误(ConcurrentHashMap.keySet)

本地使用maven编译和运行时一切都正常,但是通过ci的方式,编译、打包、发布到部署环境,运行时抛出了一条显而易见的JDK版本的错误。

13030
来自专栏晓晨的专栏

ASP.NET Core 依赖注入(DI)简介

65440
来自专栏Linyb极客之路

分布式定时任务框架之Uncode-Schedule框架源码分析

Uncode-Schedule是基于zookeeper的分布式任务调度组件,非常小巧,使用简单。 1.1. 它能够确保所有任务在集群中不重复,不遗漏的执行。 1...

32830

扫码关注云+社区

领取腾讯云代金券