ThreadPoolExecutor的Worker工作线程

ThreadPoolExecutor的Worker工作线程主要做了校验线程池状态和工作线程个数。添加工作线程并且启动工作线程。

校验线程池状态和工作线程个数代码展示

  • 需要明确两点首先,外层循环校验线程池状态。

  • 内层循环校验工作线程个数。

  • retry标记为给外循环起个名字。方便最内层的for循环跳出循环。

  • int c = ctl.get(); 获取ctl

  • int rs = runStateOf©; 拿到ctl高三位的值

  • if (rs >= SHUTDOWN &&
    ! (rs == SHUTDOWN &&
    firstTask == null &&
    ! workQueue.isEmpty()))
    return false; 这一部分是线程池状态的判断。会进入添加的条件是线程池状态是SHUTDOWN。并且阻塞队列中有任务,而且工作线程个数为0。添加一个工作线程去处理阻塞队列中的任务。
    要是上述的理想条件不满足那就false。

  • 接下来的是工作线程个数的判断。

  • int wc = workerCountOf©; 获取ctl低29位的值那就是获取工作线程的个数。

  • 如果工作线程个数大于最大值那就不添加。返回false。还有一个判断是判断当前线程是核心还是非核心。核心是基于corePoolSize去判断;非核心是基于corePoolSize去判断。

  • compareAndIncrementWorkerCount©。这里采用CAS的方式对ctl进行加1;

  • 要是上述的+1失败了。重新获取ctl的值。然后将线程的状态和之前的进行比较。要是有区别说明有变化,跳出一次外层for循环。

在这里插入图片描述

添加工作线程并启动工作线程源码分析

  • 声明了三个变量。
  • 工作线程启动没有。false。没有启动
  • 工作线程添加了没有。false。没有添加。
  • 工作线程默认为null。
  • try内部的方法分析。
  • w = new Worker(firstTask)。构建工作线程并且将任务传递进去。
  • final Thread t = w.thread;获取上面构建的word的thred对象。
  • t != null。对Thred对象进行判断。在new word的时候是通过Thred工厂去构建Thred对象。然后交给worker对象。要是为null则证明线程工厂有问题。
  • final ReentrantLock mainLock = this.mainLock;加锁保证使用workers对象以及对largestPoolSize变量相加线程的安全性。
  • int rs = runStateOf(ctl.get());再次获取线程池的状态。
  • if (rs < SHUTDOWN ||
    (rs == SHUTDOWN && firstTask == null))
    小于SHUTDOWN 这个标记说明线程池的状态是RUNNING状态正常。并且firstTask 为null添加非核心工作线程处理阻塞队列中的任务。
  • t.isAlive()。这里是校验可以添加工作线程但是不能启动线程。要是启动了那就抛出IllegalThreadStateException异常。
  • workers.add(w);这里的workers 是 private final HashSet workers = new HashSet();
  • int s = workers.size();拿到线程的线程数。
  • if (s > largestPoolSize)。当前线程数大于最大线程数更新最大线程数。
  • if (workerAdded) {
    t.start();
    workerStarted = true;
    }
    线程添加成功启动工作线程
  • if (workerAdded) {
    t.start();
    workerStarted = true;
    }
    要是添加工作线程失败处理失败的工作线程。

在这里插入图片描述

添加线程失败的操作

  • final ReentrantLock mainLock = this.mainLock;涉及到操作works需要加锁。
  • tryTerminate();添加线程失败的状态转换操作。。。。。。。。。。。。。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_50503886/article/details/131562268