线程池的介绍

线程池的好处

1.重复利用已创建的线程降低线程创建和销毁造成的消耗
2.当任务到达,可以不需要创建线程就立即执行
3.提高线程的可管理性。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程可以进行统一分配,调优和监控

线程池的实现原理

当向线程池提交一个任务之后,线程池的处理流程如下
在这里插入图片描述

1.线程池判断核心线程池里的线程是否都在执行任务,如果不是,则创建一个新的工作线程来执行任务。如果是核心线程里的线程都在执行任务,则进入下一个流程
2.线程池判断工作队列是否已经满。如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入下个流程。
3.线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务。
注意:核心线程池和线程池里面的线程数量不一致
在这里插入图片描述
threadPoolExecutor执行execute方法
1.如果当前运行的线程少于corePoolSize,则创建新线程来执行任务。
2.如果运行的线程等于或多于corePoolSize,则将任务加入BlockingQueue。
3.如果BlockingQueue满了,则创建新的线程来处理任务
4.如果创建新线程将使当前运行的线程超出maximumPoolSize,任务将被拒绝,并调用RejectedExecutionHandler.rejectedExecution()方法

线程池的参数

1.corePoolSize(核心线程数):,当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。
2.runnableTaskQueue(任务队列):用于保存等待执行的任务的阻塞队列。阻塞队列有:
ArrayBlockingQueue:基于数组结构的有界阻塞队列,
LinkedBlockingQueue:基于链表结构的阻塞队列。吞吐量高于数组
SynchronousQueue:一个不存储元素的阻塞队列。每个插入必须等待另外一个线程调用移除操作,否则插入一直阻塞,吞吐量高于链表。
3.maximumPoolSize(线程池最大数量):线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。如果使用了无界的任务队列这个参数就没有什么效果
4.threadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置名称。
5.RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,采取拒绝策略:
AbortPolicy:直接抛出异常
CallerRunsPolicy:只用调用者所在线程来运行任务
DiscardOldestPolicy:丢弃掉队列里最近的一个任务,并执行当前任务。
DiscardPolicy:不处理,丢弃掉
6.keepAliveTime:线程池的工作线程空闲后,保持存活的时间
7.TimeUnit:线程活动保持时间的单位

线程池提交任务的两种方式

public void execute(Runnable command)方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功。
public Future<?> submit(Runnable task)方法用于提交需要返回值的任务,线程池会返回一个future类型的对象,通过这个对象来判断任务是否执行成功,并且可以通过future的get方法来获取返回值,get方法会阻塞当前线程知道任务完成。

Python 线程池是一种能够提高线程利用率的技术,它通过预先创建一定数量的线程并将它们加入一个池中,当需要执行任务时,线程池中的线程会被自动分配执行任务,任务完成后线程会归还给线程池,以便下次使用。这种方式可以避免线程的频繁创建和销毁,提高线程的利用率,同时也可以控制并发线程的数量,避免系统资源的过度消耗。 下面是一个 Python 线程池的例子,用来实现多线程下载。这个例子使用了 Python 中的 ThreadPoolExecutor 类来实现线程池。 ```python import requests import concurrent.futures def download(url): response = requests.get(url) filename = url.split("/")[-1] with open(filename, "wb") as f: f.write(response.content) print(f"{filename} downloaded") if __name__ == "__main__": urls = [ "https://picsum.photos/200/300", "https://picsum.photos/250/350", "https://picsum.photos/300/400", "https://picsum.photos/350/450", "https://picsum.photos/400/500", ] with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor: executor.map(download, urls) ``` 在这个例子中,我们定义了一个 download 函数用来下载图片,然后定义了一个包含多个 URL 的列表 urls。接着,我们使用 ThreadPoolExecutor 类创建了一个最大线程数为 3 的线程池,然后使用 map 方法将下载任务分配给线程池中的线程执行。 需要注意的是,如果下载的任务需要访问共享资源,比如文件系统或数据库等,需要在 download 函数中加锁以保证线程安全。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值