首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

太完整了!彻底搞懂线程池

一、创建线程方式

继承Thread类

当一个类继承自Thread类,那么该类就是一个线程类

实现Runnable接口

实现Runnable接口,屏蔽了继承Thread类的单继承局限性,实现了对象(线程任务对象、线程对象)的分离,提高了可扩展性,解耦

实现Callable接口

和Runnable同理,并且线程任务有返回值

二、线程和线程池性能对比

创建线程的固定步骤:创建、执行、销毁首先系统创建一个线程的成本比较高,因为它涉及到与操作系统交互,当程序中需要创建大量生存期很短暂的线程时,频繁的创建和销毁线程对系统的资源消耗有可能大于业务处理,是对系统资源的消耗。针对这一情况,为了提高性能,我们就可以采用线程池。

三、线程池概述

线程池:好比水池,在该池子中存储很多线程线程池在启动时,会创建大量的线程,当我们向线程池提交任务的时候,线程池就会启动一个线程来执行该任务,等待任务执行完毕后,线程并不会死亡,而且再次返回到线程池中,称为空闲状态,等待下一次任务的执行。

线程池是一种利用池化技术思想来实现的线程管理技术,主要是为了复用线程、便利地管理线程和任务,并将线程的创建和任务的执行解耦开来,我们可以创建线程池来复用已经创建的线程来降低频繁创建和销毁线程所带来的资源消耗。

线程池关系图

四、Executor&Executors&ExecutorService

1、Executor

Executor是线程池的顶级接口,其中execute方法用于提交线程任务,参数为Runnable它是执行者接口,用于执行任务,Executor提供了execute()方法来执行已提交的Runnable任务的对象。

2、ExecutorService

比如:首先通过newFixedThreadPool()工厂方法创建一个ExecutorService的对象,这个方法创建了一个可以有具体个数的线程执行任务的线程池,然后Runnable接口的匿名实现类作为参数被传递给execute()方法,Runnable将会被ExecutorService中的一个线程来执行。execute方法是父接口Executor中的方法,该方法参数只能是Runnable对象submit方法是子接口ExecutorService中的方法,该方法参数可以是Runnable对象,也可以是Callable对象。

3、Executors

JDK对线程池也进行了相关的实现,在真实企业开发中,我们也会很少去自定义线程池,而且使用JDK中自带的线程池。

Executors是个静态工厂类,它通过静态工厂方法返回ExecutorService、ThreadFactory和Callable等类的对象。我们可以使用Executors中所提供的静态方法来创建线程池,Executors用于创建线程池对象,ExecutorService用于控制(操作)线程池

线程池分类

newCachedThreadPool线程池

源代码

代码示例

newFixedThreadPool线程池

创建指定上限的线程池newFixedThreadPool的特点是他的核心线程数和最大线程数是一致的,并且是一个固定线程数的线程池。线程池的大小一旦达到最大值后,再有新的任务提交时则放入无界阻塞队列中,等到有线程空闲时,再从队列中取出任务继续执行。

newFixedThreadPool特点:

1.创建的线程数量固定

2.创建的线程可以重复使用

3.提交一个任务,就创建一个线程,直到达到线程池的最大容量

4.有执行异常结束的线程,线程池会补充一个新的线程

5.使用无边界的队列来存储需要执行的任务

6.使用完成,需要手动关闭线程池

源代码

代码示例

newSingleThreadExecutor

源代码

代码示例

newScheduledThreadPool

源代码

代码示例

五、ThreadPoolExecutor

ThreadPoolExecutor类是ExecutorService接口的具体实现类,ThreadPoolExecutor使用线程池中的一个线程来执行给定的任务(Runnable或Callable)ThreadPoolExecutor内部的线程池包含不定数量的线程,池中线程的数量由(核心线程数量),(最大线程数量)这些变量来决定当一个任务委托给线程池执行,此时如果池中线程数少于核心线程数量,即使池中有空闲的线程,但是还是会创建一个新的线程,如果任务队列是满的,核心线程数量个线程或者更多的切少于最大线程数量的线程正在运行,也会创建一个新的线程来执行任务。

ThreadPoolExecutor构造器

所有线程池最终都是通过这个方法来创建的。

线程池源码解析

ThreadPoolExecutor构造器

参数详解

corePoolSize

maximumPoolSize

keepAliveTime 、TimeUnit

BlockingQueue

ThreadFactory

RejectedExecutionHandler

代码示例

为什么100个任务,处理第31个时出现异常?

为什么输入的结果,前面是1~10,中间是20~30,最后是10~20?

采用了提交优先级和执行优先级,并且submit底层也是调用了execute方法

提交优先级(submit):线程任务提交顺序:核心线程(1~10)、任务队列(11~20)、最大线程(21~30)

执行优先级(execute):线程任务执行顺序:核心线程(1~10)、最大线程(21~30)、任务队列(11~20)

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230108A056W200?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券