ThreadPoolExecutor线程池的理解与应用
一、线程池与进程池的区别
两个关键词:线程,进程/池
池:可以将其理解为一种容器,有其固定的大小
什么时候用线程池/进程池,分两个问题讨论
1.什么时候用池:当程序中的任务并发数远远大于计算机的承受能力时,就应该用池的概念将开启的进程数或者线程数限制在计算机的承受范围之内
2.用什么样的池:用进程池还是线程池取决于程序的类型,对于IO密集型—>线程,对于计算密集型—>进程
这就涉及到并发和并行概念的区别。并发,是指一个处理器(进程)能同时处理多个任务;并行,指的是多个处理器(进程)同时处理多个不同的任务。一般可以认为多线程用于并发任务处理,而多进程用于并行任务处理。因此,当任务是IO型的,适合用线程池的方式,因为一个线程被IO挂起,其他的线程可以继续执行;而如果任务是CPU型的,适合用进程池的方式,此时并未挂起,需要同时执行任务。
二、实用案例
下载网页的代码为例,由于是IO密集型的,可以使用线程池
代码:
# 参数times用来模拟网络请求的时间
def get_html(i, times=5):print("get page {} start".format(i))if i == 2:times *= 10time.sleep(times) # 模拟IO行为print("get page {} finished".format(i))return i, timest0 = time.time()
for i in range(5):get_html(i)
t00 = time.time()
print(f'normal exe time:{t00 - t0}')executor = ThreadPoolExecutor(max_workers=3)
# 通过submit函数提交执行的函数到线程池中,submit函数立即返回,不阻塞tasks = [executor.submit(get_html, i) for i in range(5)]
# result方法可以获取task的执行结果
t1 = time.time()
for task in tasks:print(task.result())
t2 = time.time()
print(f'thread pool exe time:{t2 - t1}')
结果如下:
get page 0 start
get page 1 start
get page 2 start
get page 0 finished
get page 3 start
(0, 5)
get page 1 finished
get page 4 start
(1, 5)
get page 3 finished
get page 4 finished
get page 2 finished
(2, 50)
(3, 5)
(4, 5)
thread pool exe time:50.0
结论:
1、有加速的作用
存在的问题:
task.result一定要等待前面任务的结果返回,才能获取后面任务的结果,这里可以用as_complete优化
加入as_complete如下:
from concurrent.futures import ThreadPoolExecutor, as_completed
import time# 参数times用来模拟网络请求的时间
def get_html(i, times=5):print("get page {} start".format(i))if i == 2:times *= 10time.sleep(times) # 模拟IO行为print("get page {} finished".format(i))return i, timest0 = time.time()
for i in range(5):get_html(i)
t00 = time.time()
print(f'normal exe time:{t00 - t0}')executor = ThreadPoolExecutor(max_workers=3)
# 通过submit函数提交执行的函数到线程池中,submit函数立即返回,不阻塞tasks = [executor.submit(get_html, i) for i in range(5)]
# result方法可以获取task的执行结果
t1 = time.time()
for task in as_completed(tasks):print(task.result())
t2 = time.time()
print(f'thread pool exe time:{t2 - t1}')
get page 0 start
get page 0 finished
get page 1 start
get page 1 finished
get page 2 start
get page 2 finished
get page 3 start
get page 3 finished
get page 4 start
get page 4 finished
normal exe time:70.0
get page 0 start
get page 1 start
get page 2 start
get page 0 finished
get page 3 start
(0, 5)
get page 1 finished
get page 4 start
(1, 5)
get page 3 finished
(3, 5)
get page 4 finished
(4, 5)
get page 2 finished
(2, 50)
thread pool exe time:50.0
结论:as_completed()方法是一个生成器,在没有任务完成的时候,会阻塞,在有某个任务完成的时候,会yield这个任务,就能执行for循环下面的语句,然后继续阻塞住,循环到所有的任务结束。从结果也可以看出,先完成的任务会先通知主线程
ThreadPoolExecutor线程池的理解与应用相关推荐
- Java Executor源码解析(3)—ThreadPoolExecutor线程池execute核心方法源码【一万字】
基于JDK1.8详细介绍了ThreadPoolExecutor线程池的execute方法源码! 上一篇文章中,我们介绍了:Java Executor源码解析(2)-ThreadPoolExecutor ...
- ThreadPoolExecutor线程池核心参数详解
理解ThreadPoolExecutor线程池的corePoolSize.maximumPoolSize和poolSize 我们知道,受限于硬件.内存和性能,我们不可能无限制的创建任意数量的线程,因为 ...
- 手写一个线程池,带你学习ThreadPoolExecutor线程池实现原理
摘要:从手写线程池开始,逐步的分析这些代码在Java的线程池中是如何实现的. 本文分享自华为云社区<手写线程池,对照学习ThreadPoolExecutor线程池实现原理!>,作者:小傅哥 ...
- ThreadPoolExecutor线程池原理
ThreadPoolExecutor线程池原理 线程池原理 1. 线程池的简单介绍 1.1 线程池是什么 1.2 线程池解决的核心问题是什么 2. 线程池的实现原理 2.1 线程池的执行流程 2.2 ...
- ThreadPoolExecutor线程池,shutdown和shutdownNow关闭线程池方式对比,以及确保线程池能够彻底关闭的一种方式
1. ThreadPoolExecutor线程池 1.1 创建线程池,构造方法的几个参数说明及创建如下. 1.2 shutdown方式关闭线程池 a. 空闲且能interrupt表示该线程处于阻塞等待 ...
- 13.ThreadPoolExecutor线程池之submit方法
jdk1.7.0_79 在上一篇<ThreadPoolExecutor线程池原理及其execute方法>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法 ...
- ThreadPoolExecutor 线程池和redisson加上手动事务踩的坑
ThreadPoolExecutor 线程池和redisson加上手动事务踩的坑 一.具体活动 0.线程池 1.redisson锁 依赖 2.redisson锁 config文件 3.redisson ...
- java corepoolsize_理解ThreadPoolExecutor线程池的corePoolSize、maximumPoolSize和poolSize
我们知道,受限于硬件.内存和性能,我们不可能无限制的创建任意数量的线程,因为每一台机器允许的最大线程是一个有界值.也就是说ThreadPoolExecutor管理的线程数量是有界的.线程池就是用这些有 ...
- ThreadPoolExecutor线程池及参数介绍
线程池类图如下: 使用Executors工具类创建的线程池,都是创建的ThreadPoolExecutor对象.这个对象的核心参数有7个: 1.corePoolSize 核心线程数,即便线程空闲也会一 ...
最新文章
- socket可能造成阻塞的函数有:connect()、accept()、读写函数、select()、poll()、gethostbyname()等
- 蓝图中实现人物移动2
- Java并发编程之线程安全
- idea docker 一键部署实战
- 少年,这有套《街霸2》AI速成心法,想传授于你……
- Facebook悄悄参加星际AI大赛,然后输了 | 中国团队夺得第四
- asp.net web.config配置节说明
- WEB版一次选择多个文件进行批量上传(Plupload)的解决方案
- 极光im java,连接极光异常是什么原因
- hackintosh黑苹果_如何构建用于编码的Hackintosh
- PMSM FOC控制 Matlab/Simulink仿真之Clark变换
- 有关《大道至简》的几点讨论~
- 关于功能结构图 信息结构图 产品结构图那点小事
- [论文分享] SoK: A Survey Of Indirect Network-level Covert Channels
- 解决Pycharm 多线程时出现错误Process finished with exit code -1073741819 (0xC0000005)
- 三级无刷交流发电机matlab模型,三级无刷交流发电机调压系统的建模及其仿真分析...
- 一站式轻监控轻运维系统nezha(上篇)
- 阿里云安装配置mysql(centos版)
- [附源码]Python计算机毕业设计餐厅订餐系统
- Android平台上集成乐橙SDK
热门文章
- python由列表中提取出来的浮点型字符串不能直接转换成整形
- python 归并排序,合并有序数组,逆序对个数
- Python3道基础练习题
- idea没有out文件夹_史上最详细没有之一的 Java JNI傻瓜级入门教程
- linux 用户态 spinlock,spinlock作用
- linux 进程间通信 dbus-glib【实例】详解四(上) C库 dbus-glib 使用(附代码)(编写接口描述文件.xml,dbus-binding-tool工具生成绑定文件)(列集散集函数)
- 【深度学习的数学】卷积神经网络的搭建
- 深入浅出python机器学习_4.3.1_岭回归的原理 4.3.2_岭回归的参数调节
- Python中的正则表达式(特征匹配)
- mysql8安装错误_Windows安装MySQL8.0.16 的步骤及出现错误问题解决方法