java基础巩固-宇宙第一AiYWM:为了维持生计,多高(多线程与高并发)_Part7~整起(打手集团【线程池】)
特此感谢,低并发编程老师的公众号里面讲的线程池一节,受益匪浅,才有了自己整理的笔记
- 先说,为啥要用线程池,之前咱们也搞过数据库连接池,为啥要有这些池化技术…
- 线程池分工要明确,单一职责哦
- 创建多少线程池合适
- 线程池主要解决两个问题:【使用线程池的好处:】
- 是当执行大量异步任务时线程池能够提供较好的性能。在不使用线程池时,每当需要执行异步任务时直接 new 个线程来运行,而线程的创建和销毁是需要开销的。而线程池里面的线程是可复用的 ,不需要每次执行异步任务时都重新创建和销毁线程。
- 相当于
降低资源消耗
, 通过重复利用已创建的线程降低线程创建和销毁造成的消耗。- 线程池是怎么复用线程的----ThreadPoolExecutor中有个内置对象Worker,每个worker都是一个线程,worker线程数量和参数有关,每个worker会while死循环从阻塞队列中取数据,
通过置换worker中Runnable对象,运行其run方法起到线程置换的效果
,这样做的好处是避免多线程频繁线程切换,提高程序运行性能。
- 线程池是怎么复用线程的----ThreadPoolExecutor中有个内置对象Worker,每个worker都是一个线程,worker线程数量和参数有关,每个worker会while死循环从阻塞队列中取数据,
提高响应速度
。 当任务到达时,任务可以不需要的等到线程创建就能立即执行
。- 提高线程的可管理性。 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行
统一的分配
,调优和监控。
- 相当于
- 二是线程池也提供了一种资源限制和管理的手段【线程池提供了一种限制和管理资源(包括执行一个任务)的方式】,比如可以限制线程的个数,动态新增线程等。每个ThreadPoolExecutor也保留了一些基本的统计数据, 比如当前线程池完成的任务数目等。
- 线程池也提供了许多可调参数和可扩展性接口 ,以满足不同情景的需要 ,开发时可以使用更方便的Executors的工厂方法, 比如 newCachedThreadPool (线程池线程个数最多可达Integer.MAX_VALUE ,线程自动回收)、 newFixedThreadPool (固定大小的线程池)、newSingleThreadExecutor (单个线程)等来创建线程池,当然用户还可以自定义
- 是当执行大量异步任务时线程池能够提供较好的性能。在不使用线程池时,每当需要执行异步任务时直接 new 个线程来运行,而线程的创建和销毁是需要开销的。而线程池里面的线程是可复用的 ,不需要每次执行异步任务时都重新创建和销毁线程。
然后,咱们先看一下线程池这里比较重要的一个关系图:
- java.util.concurrent.ScheduledThreadPoolExecutor的原理,用时到Java并发编程之美中自取 。这是一个可以在指定一定延迟时间后或者定时进行任务调度执行的线程池。
- 其内部使用DelayQueue来存放具体任务。
任务分为三种
:- 其中一次性执行任务执行完毕就结束了
- 执行任务需要实现的 Runnable 接口 或 Callable接口。
或者说Runnable 接口或 Callable 接口 实现类都可以被 ThreadPoolExecutor 或 ScheduledThreadPoolExecutor 执行
- 执行任务需要实现的 Runnable 接口 或 Callable接口。
- fixed-delay任务保证同一个任务在多次执行之间间隔固定时间
- fixed-rate 任务保证按照固定的频率执行,任务类型使用period的值来区分
- 其中一次性执行任务执行完毕就结束了
- 其内部使用DelayQueue来存放具体任务。
PART1:然后,如果让咱们自己设计一个线程池,咱们该如何考虑呢?(再次感谢低并发编程老师)
一步一步拆解框图,如下:
- 如果我自己来设计这个工具类的话(出题人给定了一个接口:public interface Executor{public void execute(Runnable r)};)。那思路就是,我写一个类实现出题人给的接口,类里面重写接口里面的方法,方法体就是最初的想要异步执行的程序,new Thread®.start();相当于不管是伙伴A,伙伴B…都来调用我这个子类中的重写过的方法就行,不用你们自己去new Thread®.start();
public ExecutorVersion01 implements Executor{public void execute(Runnable r){new Thread(r).start();} }
- Executor 框架是 Java5 之后引进的,在 Java 5 之后,通过 Executor 来启动线程比使用 Thread 的 start 方法更好,除了更易管理,效率更好(用线程池实现,节约开销)外,还有关键的一点:
有助于避免 this 逃逸问题【this 逃逸是指在构造函数返回之前其他线程就持有该对象的引用. 调用尚未构造完全的对象的方法可能引发令人疑惑的错误】
。
- Executor 框架是 Java5 之后引进的,在 Java 5 之后,通过 Executor 来启动线程比使用 Thread 的 start 方法更好,除了更易管理,效率更好(用线程池实现,节约开销)外,还有关键的一点:
- 方便了一点点,但是,要是一亿个人都调这个子类中的方法去想要异步执行,他其实也是创建了一亿个线程呀,这么多线程肯定不合适吧,你一个饭馆会招聘这么多服务员嘛,肯定不会呀,肯定要共用起来好一点呀。好,那先实现一下控制一下线程的数量
- 一个Worker貌似有点少(要是tasks队列满了怎么办,相当于客人来的很多你一个服务员手脚再麻利也忙不过来呀)。好,那先把Worker线程的数量增加一下
- 具体数量让使用者决定。调用时再传入(叫做核心线程数corePoolSize)
- 具体数量让使用者决定。调用时再传入(叫做核心线程数corePoolSize)
- 关于其中的execute()方法【
常用的提交任务的方法,也就是使用 executor.execute(worker)来提交一个任务到线程池中去
】
java基础巩固-宇宙第一AiYWM:为了维持生计,多高(多线程与高并发)_Part7~整起(打手集团【线程池】)相关推荐
- java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之OS_Part_2整起~IO们那些事【包括五种IO模型:(BIO、NIO、IO多路复用、信号驱动、AIO);零拷贝、事件处理及并发等模型】
PART0.前情提要: 通常用户进程的一个完整的IO分为两个阶段(IO有内存IO.网络IO和磁盘IO三种,通常我们说的IO指的是后两者!):[操作系统和驱动程序运行在内核空间,应用程序运行在用户空间, ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,Spring全家桶_Part1-1(Spring左膀右臂中的左膀IOC第一篇~全是概念,Spring为啥辣么6)~整起
我Java学的好好的,为什么要学spring框架呀[一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合]?或者说,成天喊简化开发,spring是如何简化开发的?或 ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,架构知识+分布式微服务+高并发高可用高性能知识序幕就此拉开(一:总览篇)~整起
PART1:项目情景发展历程:很久很久以后,敏小言和老胡开的小超市,突然发生了一些变故: 超市中除了柜台格子业务之外,还有用户.视频.签到.评论.数据处理等业务[之前,咱们项目中的用户.视频.签到.评 ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,多高(多线程与高并发)_Part9~整起(单双列集合们、ArrayList 的扩容机制、HashMap、ConcurrentHashMap )
再进入正文之前,先看看集合相关操作的时间复杂度: 本故事源自于~ 开唠: PART0: 为什么突然蹦出集合这个玩意,就是因为咱们基础那里学的"数组"不够用~: 数组一般用来保存一组 ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,手写RPC~Version07(RPC原理、序列化框架们、网络协议框架们 、RPC 能帮助我们做什么呢、RPC异常排查:ctrl+F搜超时)整起
上次Version06说到了咱们手写迷你版RPC的大体流程, 对咱们的迷你版RPC的大体流程再做几点补充: 为什么要封装网络协议,别人说封装好咱们就要封装?Java有这个特性那咱就要用?好像是这样.看 ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part2(Redis的数据结构)~整起
PART1:Redis的数据结构:5+3数据类型<----------------->数据结构[未来随着 Redis 新版本的发布,可能会有新的数据结构出现,通过查阅 Redis 官网[[ ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之OS_Part_1整起(进程线程协程并发并行、进程线程切换进程间通信、死锁\进程调度策略、分段分页、交换空间、OS三大调度机制)
PART0:OS,这货到底是个啥? OS,是个啥? OS的结构们: 存储器: 存储器的层次结构: 内存:我们的程序和数据都是存储在内存,我们的程序和数据都是存储在内存,每一个字节都对应一个内存地址.内 ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,单例模式阅读总结【单例模式不同写法、在JDK中的应用】~整起
无论是哪种设计模式,自己啃哪本书哪个博客去学,都会考虑最起码的两个问题: 我到底该咋用这种设计模式呀,直接把书上的.百度上的.博客上-的程序们抄过来? 那我该咋用呢?就算把人家程序抄过来,抄过来放在哪 ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part7(Redis常见使用(部署)方式:单机模式、主从模式、哨兵模式、集群模式)~整起
Redis持久化:RDB.AOF是针对存储在一台服务器上的数据由于存储过程被打断而发生丢失的情况的.此时,咱们肯定要考虑到,所有鸡蛋都放在一个篮子里是会出问题的. 如果服务器发生了宕机,由于数据恢复是 ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part6(Redis的应用场景、Redis是单线程的速度还快、Redis线程模型:Reactor模式、事件、发布订阅、管道)~整起
PART1-1:为什么Redis是单线程的 Redis单线程是指: Redis的网络IO和键值对读写是由一个线程来完成的.这也是 Redis 对外提供键值存储服务的主要流程.Redis的其他功能,比如 ...
最新文章
- CVPR 2022 | 阿里达摩院新技术,美体塑形一键就成
- schema类SpringMVC+Hibernate+Spring整合(二)
- ZOJ4100 浙江省赛16th Problem A
- vba执行linux命令,从VBA中的shell命令捕获输出值?
- linux终端炫酷命令,你不得不知道11个炫酷的 Linux 终端命令
- rotateleft_Java Integer类rotateLeft()方法与示例
- python 如何看到图标_如何设置CEF窗口图标(在python中)
- WPS2000中实现立体字效果(转)
- 如何基于FastReport报表工具,生成报表PDF文档展示医院处方笺的内容
- 安卓简单的通用文本编辑器介绍
- 韩立刚《计算机网络》| 第6章 应用层
- [转]杀毒软件的引擎
- 【EtherCAT实践篇】四、TwinCAT 3实验1-基本操作
- Toast的简单用法
- 1-SII--SharedPreferences完美封装
- SSM+高校食堂外卖服务小程序 毕业设计-附源码200910
- Redis 6.0 多线程连环13问
- 美国宣布成立人工智能特别委员会,要确保继续处于领先
- 中英文会计科目对照表
- 一名真学渣的秋招之路
热门文章
- 第十五章 VoIP 安全
- Praat脚本-029 | 一种更有效的校对音频内容的方案
- 与墨云同行 |低头有坚定的脚步,抬头是清晰的远方
- (四十二):Aligning Linguistic Words and Visual Semantic Units for Image Captioning
- 【深度学习】村通网之——谈谈Tensorflow Eager Execution机制之静态图和动态图的区别(一)
- SSL 1760——商店选址问题(Floyd最短路)
- 社交平台上的“引流”黑色产业链:“假聊”获粉,精准割韭菜
- 白月黑羽python_白月黑羽来帮你分析现在是选择 Python3.6 还是 Python 3.7
- selenium实战 登录后跳转到外部网站,添加多个数据 (UI-0107)分享(白月黑羽网站selenium自动化学习)
- 牛客练习赛6 珂学送分2