并发编程----4.java并发包中线程池的原理研究

2023-11-19

并发编程----4.java并发包中线程池的原理研究

java并发包中线程池ThreadPoolExecutor的原理研究

线程池的优点:线程的复用,减少线程创建和销毁带来的消耗;提供了一种资源限制和线程管理的手段,比如限制线程的个数和动态新增线程等。线程池继承 AbstractExecutorService

介绍
  1. ctl:原子变量,用来记录线程中的线程池状态和线程个数,类似于ReentrantReadWriteLock使用一个变量state保存两种信息

    1. 高三位表示线程池的状态(Integer 32位)
    2. 29位记录线程池的个数
  2. 线程池的状态

    1. shutdown:拒绝新的任务但是处理阻塞队列中的任务
    2. stop:拒绝新任务并且抛弃阻塞队列中的任务,同时中断正在处理的任务
    3. tidying:所有的任务执行完了之后包括阻塞队列中的线程,将调用terminated
    4. terminated:终止状态
    5. running:接受任务并且处理阻塞队列中的任务
  3. 线程状态转化

    1. running–>shutdown
    2. runining/shutdown–>stop
    3. shutdown–>tidying
    4. stop–>tidying
    5. tidying–>terminated
  4. 线程池参数

    1. corePoolSize: 线程池核心线程数
    2. workQueue: 用于保存等待执行任务的阻塞队列,例如:数组有界ArrayBlockingQueue、基于链表的LinkedBlockingQueue、最多一个元素的SynchronousQueue,优先队列PriorityBlockingQueue
    3. maximunPoolSize:线程池最大线程数量
    4. ThreadFactory:创建线程工厂
    5. RejectedExecutionHandler:饱和策略,当队列满且线程数达到MaximumPoolSize后采取的策略,比如抛出异常,AbortPolicy;CallerRunsPolicy调用者所在的线程运行任务。DiscardOldestPolicy丢弃一个任务执行当前任务。DiscardPolicy默默抛弃不抛出异常
    6. keeyAliveTime:存活时间,当前线程比核心线程多,并且处于闲置状态,则这些闲置的线程能存活最大时间
  5. 线程池类型

    1. newFixedThreadPool
      1. 创建一个核心数和最大线程数都为n的线程池,并且阻塞队列为Integer.MAX_VALUE。keekAliveTime=0说明线程个数比核心线程多并且空闲则回收
    2. newSingleThreadExecutor
      1. 创建一个核心数和最大线程数都为1的线程池,并且阻塞队列为Integer.MAX_VALUE。keekAliveTime=0说明线程个数比核心线程多并且空闲则回收
    3. newCacheThreadPool
      1. 按需创建线程的线程池,初始线程个数为0.最多线程数为Integer.MAX_VALUE,并且阻塞队列为同步队列,keepAliveTime=60说明只要任务只要在60s内就被回收。当加入同步任务就会马上被执行,同步队列中最多只有一个任务
        在这里插入图片描述
  6. mainLock为独占锁,用来控制新增worker线程操作原子性,termination是该锁对应的条件队列,在线程调用个awaitTermination时存放阻塞的线程。

  7. Work继承AQS和Runnable接口,是具体承载任务的对象,简单实现了不可重入锁,其中state=0为锁未被获取状态,state=1表示获取状态-1为默认。firstTask执行的第一个任务。

  8. DefaultThreadFactory是线程工厂,newThread 方法是对线程一个修饰。其中poolNumber是个静态原子变量,用来统计线程工厂个数。threadNumber统计线程工厂创建了多少线程。

  9. 源码分析

    1. public void execute(Runnable command)提交任务
      1. 当当前线程数个数小于corePoolSize,会向workers里面新增核心线程执行该任务
      2. 当大于或者等于corePoolSize放入任务队列(workQueue)中,如果当前线程池状态不是running的话就抛弃新任务
      3. 添加任务成功,则对线程进行第二次的状态校验,这是因为任务放入任务队列后,执行代码前任务可能已经变化,这里进行校验,如果是非running状态就从队列里面移除任务,并且执行拒接策略。如果二次校验通过,重新判断线程池里面是否有线程,如果没有新增一个线程。
      4. 如果任务失败,说明任务队列已满,尝试开始新的线程,如果当前线程个数>maximumPoolSize则执行拒绝策略。
    2. 添加任务
      1. 检查队列是否只在必要的时候为空(返回情况:stop,tidying,terminated;shutdown并且队列中到一个一个任务;shutdown并且队列为空)
      2. cas增加线程个数(超出最大线程数返回),成功返回,失败查看是否是状态改变是就返回,不是就重新cas
      3. 创建worker,使用mainLock实现wokers同步,
      4. 检查状态是否被shutdown了,是就返回不是添加任务,
      5. 成功启动任务。
    3. 工作线程worker的执行
      1. 获取任务,如果任务为null则执行清理工作,如果不为空,获取该任务的锁,执行相关任务,统计worker完成了多少任务,并且释放锁(加锁的目的是为了防止其他线程调用了shutdown,阻止当前任务的执行)
      2. 清理操作,统计完成任务数量,从工作集中删除当前任务,尝试设置为terminated状态。如果当前线程<核心个数增加。
    4. shutdown操作
      1. mainLock锁住
      2. 权限检查,调用的线程师傅有关闭的权限,没有抛出异常
      3. 设置为shutdown,是直接返回,不是设置为shutdown
      4. 设置中断标志、尝试设置为terminated,设置所有空闲线程中断标志。尝试获取worker自己的锁,成功则设置中断标志,目的是为了阻塞要从任务队列中获取任务的空闲队列。方法:使用cas 设置当前线程池的状态为tidying,设置成功就执行terminated,设置为terminated,激活所有因为调用条件变量await系列方法阻塞的所有线程。
      5. 解锁
    5. shutdownNow操作
      1. 不接受新的任务也不执行任务队列中的任务,正在执行的任务会立刻被中断,该方法会返回
    6. awaitTermination操作
      1. 当前线程不会被阻塞,知道线程状态变为terminated才返回,或则等待时间超时才返回。

java并发包中线程池ScheduledThreadPoolExecutor的原理研究

指定一个延迟时间后或者定时进行任务调度执行的线程池。ScheduledThreadPoolExecutor继承了ThreadPoolExecutor并实现了ScheduledExecutorService,线程池队列是DelayedWorkQueue。

  1. 介绍
    1. state 状态:ScheduledFutureTask是具有返回任务的继承自FutureTask。FutureTask内部有一个state用来表示任务状态
      1. 初始状态:new;执行中状态:completing : 执行中状态;normal:正常运行结束状态;exceptional:运行中异常;cancelled:任务取消;interrupting: 正在中断;interrupted:已经中断。
      2. 状态装换:new–>completing -->normal;new–>completing–>exceptional;new–>canceled;new–>interrupting–>interrupted
    2. period 任务类型:
      1. period=0:任务是一次性的
      2. period<0:任务是固定延迟时间可重复执行任务
      3. period>0:任务是固定频率的定时可重复执行任务
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

并发编程----4.java并发包中线程池的原理研究 的相关文章

  • iOS并发编程(一)-简介

    一个菜鸟的自我修养 就是在低级职位上不抓狂 当一个优秀的菜鸟 就是为了有一天不当菜鸟 瞅准机会迅速脱离菜鸟轨道 然后一路飞翔到世界的尽头 接下来系统的学习下并发编程 会有几篇吧 不多说 走起 简介 1 异步设计方式 传统并发编程模型是线程
  • 线程池的主要处理流程及常用方法

    线程池的主要处理流程及常用方法 更多优秀文章 请扫码关注个人微信公众号或搜索 程序猿小杨 添加 一 主要处理流程 当调用线程池execute 方法添加一个任务时 threadPoolExecutor execute 具体代码如下 priva
  • Qt基础之三十:百万级任务并发处理

    在实际的开发过程中 经常会遇到要处理大量任务场景 比如说压缩文件夹中的所有文件 对文件夹中的所有文件加密 上传文件夹中的所有文件到ftp等等 这里说百万级并不夸张 理论上文件夹中有任意多个文件都是可以的 本文以压缩文件夹中的100万张jpg
  • 无锁和偏向锁有什么区别?

    无锁和偏向锁是 Java 中的两种轻量级锁实现 它们和重量级锁相比 具有更高的性能和更低的开销 它们之间的区别如下 无锁 CAS 自旋锁 无锁是一种不需要使用锁的同步技术 它的实现依赖于 CAS Compare And Swap 操作 通过
  • Android多线程下载断点续传

    先上图看卡结果 GITHUB Android多线程下载断点续传 下载杵这儿 如图所示点击下载就开始下载 点击停止就会停止再次点击下载就会接着下载了 设计思路是这样的 首先通过广播将下载信息传递给DownService DownService
  • python实现线程池

    参照c 的线程池 使用python的threading库实现线程池 import threading import time 线程池的任务 包含一个可调用对象和一个参数数组 class ThreadTask object def init
  • java高并发的处理--锁机制

    对于我们开发的网站 如果网站的访问量非常大的话 那么我们就需要考虑相关的并发访问问题了 而并发问题是绝大部分的程序员头疼的问题 但话又说回来了 既然逃避不掉 那我们就坦然面对吧 今天就让我们一起来研究一下常见的并发和同步吧 为了更好的理解并
  • 处理高并发、大数据存储的网站技术架构

    本文转载自 https zhuanlan zhihu com p 24669514 大型网站技术架构剖析 高并发 大流量 40亿 PV page view 3 5亿 IP 高可用 高可用MySQL 7 24小时不间断运行 海量数据 用户分布
  • python 线程池使用

    前段时间发现了一个 人工智能学习网站 通俗易懂 风趣幽默 分享一下给大家 学习链接 文章目录 线程池使用 1 线程池介绍 2 使用方法 2 1 threadpool 2 2 ThreadPoolExecutor submit as comp
  • Java多线程工具包java.util.concurrent---ExecutorService

    什么是ExecutorService java util concurrent ExecutorService 接口表示一个异步执行机制 使我们能够在后台执行任务 因此一个 ExecutorService 很类似于一个线程池 实际上 存在于
  • 线程池源码分析(一)

    最近在阅读 阿里巴巴Java开发手册 的时候 书中有这么一段话 线程池这块理解不是很深 今天就抽时间重新学习一遍 对于书中的问题分析完成后答案便一目了然 创建线程池的一个方式 ExecutorService e Executors newF
  • Linux---多线程、线程池

    多线程 线程概念 线程就是进程中的一条执行流 负责代码的执行调度 在linux下线程执行流是通过pcb实现的 一个进程中可以有多个pcb 这些pcb共享进程中的大部分资源 所以线程被称为一个轻量级进程 Notes 进程是系统进行资源分配的基
  • php消息队列的应用

    欢迎加入 新群号码 99640845 最近打算开发一个新功能 计划应用消息队列 以前对消息队列都是简单的理论了解 真正应用之后把自己的感觉和一些理解整理下来 说正事分割线 具体的业务场景如下 用户下单 生成订单 支付 返回支付信息 就是正常
  • java 关于锁常见面试题

    1 synchronized作用于静态方法和非静态方法的区别 非静态方法 给对象加锁 可以理解为给这个对象的内存上锁 注意 只是这块内存 其他同类对象都会有各自的内存锁 这时候在其他一个以上线程中执行该对象的这个同步方法 注意 是该对象 就
  • 线程池七大参数

    线程池的七大参数是指使用 ThreadPoolExecutor 创建线程池时所设置的 7 个参数 分别为 public ThreadPoolExecutor int corePoolSize int maximumPoolSize long
  • Semaphore 源码分析

    需要提前了解的知识点 AbstractQueuedSynchronizer 实现原理 类介绍 Semaphore 信号量 是用来控制同时访问特定资源的线程数量 它通过协调各个线程 以保证合理的使用公共资源 比如控制用户的访问量 同一时刻只允
  • 从操作系统层面理解同步、异步、阻塞、非阻塞

    同步和异步描述调用者会不会主动等待函数的返回值 举个例子 public void method int result otherMethod 像上面这种形式就叫同步 result 会一直等待 otherMethod 方法执行完毕并拿到返回值
  • 线程连接池

    第一种 Executors newCacheThreadPool 可缓存线程池 先查看池中有没有以前建立的线程 如果有 就直接使用 如果没有 就建一个新的线程加入池中 缓存型池子通常用于执行一些生存期很短的异步型任务 package tes
  • JAVA使用线程池查询大批量数据

    前言 在开发过程中可能会碰到某些独特的业务 比如查询全部表数据 数据量过多会导致查询变得十分缓慢 虽然在大多数情况下并不需要查询所有的数据 而是通过分页或缓存的形式去减少或者避免这个问题 但是仍然存在需要这样的场景 比如需要导出所有的数据到
  • django高并发部署

    django高并发部署

随机推荐

  • 解决报错:Uncaught TypeError: Cannot read properties of undefined (reading ‘install‘)

    在做vue2项目时出现如下错误 页面空白且控制台出现如下错误 报错内容 Uncaught TypeError Cannot read properties of undefined reading install at Vue use vu
  • Anaconda + jupyter notebook + jupyter lab环境配置

    1 更换源 1 1 pip源 pip config set global index url https pypi tuna tsinghua edu cn simple pip config set install trusted hos
  • SQL SERVER2008存储过程加密与解密

    前言 我们在设置数据库存储过程时经常会用到加密 如果遇到版本更新需要修改存储过程时 如果设计数据库时的存储过程没有留存 所以就必须用到存储过程的解密了 原来自己有个解密存储过程在SQL2000下应用无问题 后来升级到SQL2008后不好用了
  • 4.网络爬虫—Post请求(实战演示)

    网络爬虫 Post请求实战演示 POST请求 GET请求 POST请求和GET请求的区别 获取二进制数据 爬 百度官网 https www baidu com logo实战 发送post请求 百度翻译实战 使用session发送请求 模拟登
  • 微信小程序部署到线上环境

    微信小程序部署到线上环境 一 微信小程序申请 申请 并认证 未认证不能发布 认证需要300元 目前只支持企业认证 详细见官网说明 https mp weixin qq com cgi bin registermidpage action i
  • mac os mysql忘记root密码_mac上mysql报错以及root密码忘记解决办法

    1 对于前者ERROR 2002 HY000 Can t connect to local MySQL server through socket tmp mysql sock 2 这个错误 一般是mysql服务没开 命令行下执行sudo
  • java8的时期和时间

    文章目录 旧版日期时间的问题 新版日期时间介绍 Java util date java sql date SimpleDateFormatter calendar java8日期 DateTimeFormatter 计算 java8之前 j
  • Python学习 第五章 图形界面设计

    第五章 图形界面设计 1 常用的 Python GUI 库 1 1 Tkinter 1 2 wxPython 1 3 创建GUI程序 2 创建Windows窗口 3 几何布局管理器 3 1 pack 包装 3 2 grid 网格 3 3 p
  • leetcode移动零c++

    给定一个数组 nums 编写一个函数将所有 0 移动到数组的末尾 同时保持非零元素的相对顺序 示例 输入 0 1 0 3 12 输出 1 3 12 0 0 说明 必须在原数组上操作 不能拷贝额外的数组 尽量减少操作次数 整体思路 题目中都出
  • 软件项目经理的基本职责

    软件项目经理的基本职责 1 制定项目计划 并根据各种变化修改项目计划2 实施 项目的管理 开发 质量保证过程 确保客户的成本 进度 绩效和质量目标 3 制定有效的项目决策过程4 确保在项目生命周期中遵循是实施公司的管理和质量政策5 选择一个
  • VC++ CComboBox自绘(选择下拉列表框)

    效果图 头文件定义 CSWCheckComboBox h pragma once class CSWCheckComboBox public CComboBox DECLARE DYNAMIC CSWCheckComboBox 成员私有结构
  • gdal解析tif

    bool HandleTif ReadTif tif文件读取 std string name D XX xx tif const char charName name c str 注册 GDALAllRegister 以防中文名不能正常读取
  • Docker本地镜像推送到私有库

    Docker Registry是官方提供的工具 可以用于构建私有镜像仓库 1 下载镜像Docker Registry docker pull registy 2 运行私有库Registry 相当于本地有个私有Docker hub docke
  • 计算机基础——Excel 2010

    天软备考交流群 365218976 1 Excel 2010的基本操作 1 1 Excel的窗口界面 1 2 工作簿与工作表 1 3 单元格区域的管理 1 4 工作表的管理 1 5 输入和编辑数据 1 6 行 列和单元格的管理 1 7 批注
  • java代码引用jar包中文件的方法

    jar是一个单独的文件 里面的文件称之为资源 有两种方法获取 里面的资源文件 一般将资源文件放到resources文件夹中 1 推荐 静态和非静态方法中都能用 ClassName class getClassLoader getResour
  • 刷脸支付服务商抓住机会迎头赶上

    科技改变未来并不是一句口号 就拿买东西来讲 以前人们都是一手交钱一手交货 拿到大额的纸币 还要验真假 而现在移动支付成为主要付款方式 只要一部手机 扫一扫就能付款 一开始也有很多人不习惯手机支付 因为觉得没有现金实在 整天就是一堆数字转来转
  • 前端手写(正则、字符串、函数)

    1 实现千位分隔符 保留三位小数 parseToMoney 1234 56 return 1 234 56 parseToMoney 123456789 return 123 456 789 parseToMoney 1087654 321
  • ajax 传回underfined,$.jquery ajax返回的数据(json)显示为’undefined’

    这里我有一个简单的 PHP脚本 它以json格式显示数据库中的一些值 source GET source query MysqL query SELECT FROM images WHERE big thumb source results
  • Anaconda安装教程及numpy环境配置

    一 下载Anaconda 下载地址 https www anaconda com 二 安装Anaconda 1 进入官网后 看不懂英文可以先将网页翻译成中文 然后点击产品 gt 个人版 如图进入下载页面 2 可以直接点击下载 也可以滚动到页
  • 并发编程----4.java并发包中线程池的原理研究

    并发编程 4 java并发包中线程池的原理研究 java并发包中线程池ThreadPoolExecutor的原理研究 线程池的优点 线程的复用 减少线程创建和销毁带来的消耗 提供了一种资源限制和线程管理的手段 比如限制线程的个数和动态新增线