java线程池源码解析:ThreadPoolExecutor源码,execute方法、addWorker方法解析

本文主要是介绍java线程池源码解析:ThreadPoolExecutor源码,execute方法、addWorker方法解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.  概述

线程池 的作用不用太说了,线程池会按照一定的规则,创建和维护一定数量的线程。这些线程可以被循环利用,来处理用户提交的任务。对比不同线程池的使用方式,节省了频繁的创建和销毁线程带来的性能开销。

2.  概念理解

2.1 工作线程(worker)

指的是当先线程池用于处理任务的worker对象,每个worker对象内部持有一个thread对象。

2.2 任务

调用方,要执行的业务鹿皮,一半应该是callable或者Runnable的实现。

2.3 任务队列

线程池哪位维护了一个队列,用来存储待处理的任务,每个线程都可以从该队列获取任务进行处理。

2.4 核心线程数

线程池哪部需要维持的一个最小的数量的工作线程,工作线程数量不足这个数量的时候,新来的任务都会提交一个新的工作线程,任务不会放入 队列。工作线程数到达这个数量的时候,新来的的任务,都会放入这个队列中。所有的工作线程,都回去轮训这个任务队列。

2.5 线程池一共有5种工作状态。

running:正常运行的状态,此时,可以正常接受和处理任务。

shuntdown: 此时不可以接收新的任务,但是可以正常处理,但是不再接受新的任务,并且终端空闲的工作状态

stop:  此时清除队列中的没有处理的任务,中断所有的工作线程。

tidying: 从shuntdown  或者 stop 自动流转到这个状态。任务列表和工作线程,都为空。

terminated: 终止状态,从tidiying状态自动流转到此状态。此时队列中的任务为空,工作线程列表为空,并且已经执行完 terminated 回调函数。


// Integer.SIZE = 32 ,所以这个 COUNT_BITS = 29,意思是存储工作线程数的二进制为占29位
private static final int COUNT_BITS = Integer.SIZE - 3;/*CAPACITY 实际上就是2的29次方减1,具体的实际数值是多少不重要,重点是关注二进制表示:1左移29位实际上就是:0010 0000 0000 0000 0000 0000 0000 0000再减个1后得到的就是:0001 1111 1111 1111 1111 1111 1111 1111所以这个CAPACITY的有效位就是29个1
*/ 
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;/* --- 状态值的定义 开始 ---*/// runState is stored in the high-order bits
// 状态值存储在高(3)位
/*
-1的二进制表示:1111 1111 1111 1111 1111 1111 1111 1111 (补码标识法)
-1左移29位之后:111 00000 0000 0000 0000 0000 0000 0000 (左侧切断,右侧补0)
*/
private static final int RUNNING    = -1 << COUNT_BITS;/*
0的二进制表示:0000 0000 0000 0000 0000 0000 0000 0000
0左移29位之后:000 00000 0000 0000 0000 0000 0000 0000 (还是0)
*/
private static final int SHUTDOWN   =  0 << COUNT_BITS;/*
1的二进制表示:0000 0000 0000 0000 0000 0000 0000 0001
0左移29位之后:001 00000 0000 0000 0000 0000 0000 0000 
*/
private static final int STOP       =  1 << COUNT_BITS;/*
2的二进制表示:0000 0000 0000 0000 0000 0000 0000 0010
0左移29位之后:010 00000 0000 0000 0000 0000 0000 0000 
*/
private static final int TIDYING    =  2 << COUNT_BITS;/*
3的二进制表示:0000 0000 0000 0000 0000 0000 0000 0011
0左移29位之后:011 00000 0000 0000 0000 0000 0000 0000 
*/
private static final int TERMINATED =  3 << COUNT_BITS;/*针对以上5个变量的总结,右侧的29位都是0,RUNNING的二进制以1打头,转换为整型为负值,所以这几个状态的整型数值从上到下依次增大。
*//* --- 状态值的定义 结束 ---*//*将状态和线程数整合到一个数值的方法(利用二级制的或运算)rs:一定是上面5个状态中的一个wc:线程数是个不固定的正数值因为rs的右侧29为都是0,而wc在逻辑上限制了其最大值不能超过CAPACITY,所以wc的前3位一定是0,所以整合之后的数值实际上是:rs的前三位 + wc的后29位
*/
private static int ctlOf(int rs, int wc) { return rs | wc; }/*从整合后数值c中拆分出来状态值状态值 = c的前3位 + 29个0c 和 CAPACITY取反 做与运算CAPACITY:0001 1111 1111 1111 1111 1111 1111 1111取反之后:1110 0000 0000 0000 0000 0000 0000 0000因为前3位都是1,所以无论c的前3位是什么,与运算后都会保留c的前3位不变因为后29位都是0,所以无论c的后面是什么,与运算后都会变为29个0这样就还原出状态值。
*/
// Packing and unpacking ctl
private static int runStateOf(int c)     { return c & ~CAPACITY; }
/*从整合后数值c中拆分出来工作线程数工作线程数 = 3个0 + c的后29位c 和 CAPACITY 做与运算CAPACITY:0001 1111 1111 1111 1111 1111 1111 1111因为前3位都是0,所以无论c的前3位是什么,与运算后都会变为0因为后29位都是1,所以无论c的后面是什么,与运算后都保持c的后29位不变这样就还原出了工作线程数的值。
*/
private static int workerCountOf(int c)  { return c & CAPACITY; }// 把整合后的值包装到一个原子变量中,下文称控制标识
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

这篇关于java线程池源码解析:ThreadPoolExecutor源码,execute方法、addWorker方法解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/984747

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听