线程池ThreadPoolExecutor

news2024/11/30 2:36:16

线程池的生命周期

 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

 ThreadPoolExecutor使用一个ctl变量代表两个信息,线程池的运行状态 (runState) 和 线程池内有效线程的数量 (workerCount),高三位表示状态。

workerCount:线程池内有效线程的数量,工作线程允许开始,不允许停止,使用ctl的低29位表示

runState:线程的生命周期,是有序的随时间递增,也就是状态不可逆的。

    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;

    // Packing and unpacking ctl
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    private static int ctlOf(int rs, int wc) { return rs | wc; }
状态描述

   状态位

(高三位)

RUNNING运行状态,允许提交新的任务,正常处理阻塞队列中的任务111
SHUTDOWN关闭状态,不允许提交新的任务,但可以正常处理队列中的任务000
STOP停止状态,不允许提交新的任务,也不处理队列中的任务,也会停止正在运行的状态001
TIDYING整理状态,所有的任务都停止,workerCount清零,将会调用terminated()010
TERMINATED终止状态,terminated()方法调用完成后的状态011

 

 任务调度

execute

  public void execute(Runnable command) {
//判断任务是否为空
        if (command == null)
            throw new NullPointerException();
//获取当前工作线程数量和线程状态
        int c = ctl.get();
//如果工作线程数小于核心线程数
        if (workerCountOf(c) < corePoolSize) {
//增加一个核心线程去执行任务
//增加成功结束
            if (addWorker(command, true))
                return;
//增加失败,再次获取当前线程池的工作线程数量和线程状态
            c = ctl.get();
        }
//如果当前线程池正在运行
//将任务放入阻塞队列
        if (isRunning(c) && workQueue.offer(command)) {
//插入成功★
//再次获取当前线程池的工作线程数量和线程状态
            int recheck = ctl.get();
//此时(并发情况)线程池非Running状态
//将任务移除阻塞队列
            if (! isRunning(recheck) && remove(command))
//移除成功,执行抛弃策略
                reject(command);
//移除失败,则判断当前的工作线程数是否为0
            else if (workerCountOf(recheck) == 0)
//为0则增加一个空工作线程,(去执行★之前插入成功的任务)
                addWorker(null, false);
        }
//创建一个非核心线程去执行任务
        else if (!addWorker(command, false))
//创建失败,执行拒绝策略
            reject(command);
    }

 submit

submit传入任务以及其返回值类型,如果任务是Runnable的话上会将任务包装成Callable任务也就是RunnableFuture,然后再丢给execute去执行。

executesubmit
是否有返回值有,需要阻塞去获取
外部对的异常处理无法处理,使用execute任务出现异常,外部无法感知可以在Future.get()中捕获异常,进行处理
执行过程直接放到工作线程如果参数是Runnable则需要包装成Callable然后执行execute去执行
接受任务类型RunnableRunnable、Callable

阻塞队列

线程池使用阻塞队列将要执行的任务与线程分开,用生产者和消费者模型实现。

当任务数量超过核心线程数,后续任务就会放入阻塞队列中进行排队。

因为实现了BlockingQueue所以都是线程安全的。

Array

Blocking

Queue

Linked

Blocking

Queue

Priority

Blocking

Queue

Delay

Queue

Synchronous

Queue

Linked

Transfer

Queue

Linked

Blocking

Deque

名称数组有界阻塞队列链表有界阻塞队列优先级无界阻塞队列使用优先级队列实现的无界阻塞队列不存储元素的阻塞队列链表无界阻塞队列链表双向阻塞队列
实现的方式数组链表自定义优先级使用

Priority

Blocking

Queue

链表、tryTransfer双向链表
队列长度自定义Integer.MAX_VALUE无界无界无界无界无界
特点支持公平和非公平锁可以自定义compareTo()方法进行排序,不能保证同优先级元素的排序可以指定所有才能从队列中获取当前元素,延迟期满了之后才能从队列种获取元素每put操作必须等待take,否则不能put成功。支持公平和非公平锁。

LinkedBlockingQueue多了tryTransfer,transfer方法

头部和尾部都可以插入元素,多线程并发时们可以将所得竞争降低到一半

任务拒绝

当线程池的缓存队列已满,线程数也达到了maximumPoolSize 时,再新增任务就会触发拒绝策略。

拒绝策略收到三个参数影响:corePoolSize 、maximumPoolSize 、workQueue 。

当任务提交后,如果没达到核心线程数,则会直接创建核心线程运行,如果达到了核心线程数则会放入队列中等待,当任务数大于workQueue.size+maximumPoolSize则触发拒绝策略。

名称AbortPolicy CallerRunsPolicy DiscardPolicy DiscardOldestPolicy 
策略抛出异常,终止任务使用调用线程执行任务,当触发拒绝策略,只要线程池没有关闭的话,则使用调用线程直接运行任务直接丢弃丢弃workQueue队列最老任务,添加新任务
场景需要捕获异常进行处理适合并发小,性能要求不高且不允许失败的情况。但是,由于调用者自己运行任务,如果任务提交速度过快,可能导致程序阻塞,性能效率上必然的损失较大允许任务不执行允许任务不执行,且希望执行最新的任务
JDK是否默认使用

常用线程池

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/48992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 数据库存储引擎

目录 一、存储引擎简介 二、MyISAM存储引擎 1、MylSAM介绍 2、MyISAM表支持3种不同的存储格式 3、MylSAM的特点 4、MyISAM使用的生产场景 三、InnoDB存储引擎 1、InnoDB介绍 2、InnoDB的特点 3、InnoDB适用生产场景 4、MyISAM和InnoDB的区别 四、查看和修改存储引擎…

CloudAlibaba - Nacos服务注册与配置中心

文章目录一.CloudAlibaba简介1. 介绍2. 依赖3. 主要组件4. 资料文档二.Nacos服务注册与发现1. 简介2. Nacos安装3. Nacos服务注册3.1 注册服务生产者3.2 服务消费者注册和负载4. Nacos服务中心对比三.Nacos配置中心1. 基础配置搭建2. Nacos中添加配置信息2.1 Nacos中的匹配规则…

单商户商城系统功能拆解40—分销应用—分销设置

单商户商城系统&#xff0c;也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法&#xff0c;例如拼团&#xff0c;秒杀&#xff0c;砍价&#xff0c;包邮…

前端js传入Long类型精度丢失解决办法

目录 问题背景 解决过程 1.对比数据库数据 2.查询资料 解决方法 问题背景 在进行业务开发的 时候发现更新数据库中的一条数据没有成功&#xff0c;查看SQL日志发现SQL正常执行无错误信息&#xff0c;但是受影响行数为0&#xff0c;但是数据是从前端传过来的 &#xff0c;一…

面试官:MySQL explain你会关注哪些字段

编号字段名称字段说明值重要性1idSELECT查询序号&#xff0c;即为sql语句执行的顺序。数字越大越优先执行1、2、3...★★2select_typeselect类型&#xff0c;用于区分是普通查询、子查询或联合查询simple&#xff1a;简单的查询&#xff0c;不含子查询和联合查询primary&#x…

玩机搞机---卸载内置软件 无root权限卸载不需要的软件 安全卸载

目前的机型出厂都会自带一些内置软件。个别的还无法删除。各种弹窗广告 等等占用系统资源。操作卡顿。而很多卸载软件有需要root权限才可以运行。那么有没有方法可以无需root就可以卸载内置软件呢。答案是有的。而且方法很多。今天的帖子就列举一下常用的操作步骤 操作前了解的…

自己搭建网站【搭建网站】

现在搭建网站也不只是企业公司商家的专利&#xff0c;很多个人用户都想拥有属于自己的一个网站。那么怎么自己搭建网站呢&#xff1f;下面给大家简单说说。 一、申请域名 域名是访问网站的地址&#xff0c;这是必须要有的&#xff0c;可以在域名服务商网站上申请。申请域名需要…

科普-鸟哥私房菜中的“od -t oCc /etc/issue”的意思

文章摘录展示 看到这里是困惑的&#xff0c;毕竟看这里没有写oCc 的格式 既然文章不能找到答案&#xff0c;那么&#xff0c;我们看详细的说明吧&#xff08;man od&#xff09; 如图&#xff0c;想必我们应该很清楚了 &#xff0c;o[size] 对应的参数oC &#xff0c;就可以很…

2022.11.27Find a way HDU - 2612

Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki. Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city.…

MySql索引详解-各种索引的定义与区别和应用

MySql索引详解-各种索引的定义与区别和应用一、索引基础&#xff1a;增删改查1.新增索引的几种方式2.删除索引的几种方式3.修改索引的几种方式4.查询索引的几种方式二、索引的分类1.主键索引2.唯一索引3.普通索引4.复合索引5.全文索引三、总结什么是索引&#xff1f;索引的作用…

【DL with Pytorch】第 6 章 : 用循环神经网络分析数据序列

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

PointRend 原理与代码解析

paper&#xff1a;PointRend: Image Segmentation as Rendering code1&#xff1a;https://github.com/facebookresearch/detectron2/tree/main/projects/PointRend code2&#xff1a;https://github.com/open-mmlab/mmsegmentation/tree/master/configs/point_rend 创新点…

[附源码]Python计算机毕业设计Django的花店售卖系统的设计与实现

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

[附源码]SSM计算机毕业设计学习资源共享与在线学习系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

全局路由拦截、局部路由拦截

引入&#xff1a; 看下面这个效果&#xff1a; 每次我们在点击一个功能时&#xff0c;它就会跳转到登录页面&#xff0c;意思就是让我们先登录&#xff0c;登录之后再进行功能操作&#xff1b;但是如果我们登录了&#xff0c;它就不会跳转&#xff0c;这是什么原理呢&#x…

vue3Blog首页基础布局样式规划

思考:我们已经安装了一个ant-design-vue的组件库,是否还可以安装其他的UI组件库混合使用? 答案是可以的,比如这个组件库没有要用到的组件,但另外一个组件有,我们完全可以再安装,单独将某一个使用到的组件引入即可,当项目打包的时候也不会说把所有的安装的都打包进去,只…

VS Code + Vue 开发环境搭建

1、下载并安装 Visual Studio Code 2019 2、Visual Studio Code 2019安装成功后&#xff0c;打开VS Code 工具点击左侧【扩展】菜单&#xff0c;在搜索栏中输入 Chinese 查找中文语言汉化包插件下载安装&#xff0c;然后重启VS Code 3、点击左侧【扩展】菜单&#xff0c;在搜…

【JS】数据结构之图结构

文章目录基本概念图的实现基本概念 什么是图&#xff1f; 图是一种数据结构&#xff0c;与树结构有些相似&#xff08;在数学的概念上&#xff0c;树是图的一种&#xff09;树结构是一对多的关系&#xff0c;而图结构是多对多的关系比如导航的最优路径&#xff1a;可以看成多个…

【Pandas数据处理100例】(一百):Pandas中使用filter()过滤器实现数据筛选

前言 大家好,我是阿光。 本专栏整理了《Pandas数据分析处理》,内包含了各种常见的数据处理,以及Pandas内置函数的使用方法,帮助我们快速便捷的处理表格数据。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmPandas版本:1.3.5N…

Oracle的学习心得和知识总结(八)|Oracle数据库PL/SQL语言GOTO语句技术详解

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《Oracle Database SQL Language Reference》 2、参考书籍&#xff1a;《PostgreSQL中文手册》 3、EDB Postgres Advanced Server User Guid…