Java 异步编程——Java内置线程池(Executor 线程池)

知道线程池是什么以及解决什么问题

线程池(Thread Pool)是一种基于池化思想管理线程的工具,用于管理和复用线程的技术。它由一组预先创建的线程组成,这些线程可以在需要时被重复使用来执行多个任务,从而避免了频繁创建和销毁线程的开销。

线程创建是有一定的开销,频繁创建销毁线程的开销会降低系统性能。线程池可以维护多个已创建的线程,一方面避免了处理任务时频繁创建销毁线程开销的代价,另一方面避免了线程无上限创建导致资源浪费及过分调度问题,保证了对系统资源的充分利用。

线程池解决的核心问题就是资源管理的问题。在并发环境下,任意时刻都无法确定有多少任务需要执行,需要多少资源投入使用。由于这些不确定因素在使用多线程时会带来以下若干问题:

  1. 频繁创建和销毁线程带来较大的开销。
  2. 使用不当出现无限制地创建线程,不停的系统申请资源,缺少抑制手段,容易引发系统资源耗尽的风险。
  3. 系统无法合理有效地管理与分配资源,降低系统的稳定性。

那么,使用线程池可以带来有效解决上述可能出现的一系列问题:

  1. 降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。
  2. 提高响应速度:任务到达时,无需等待线程创建即可立即执行。
  3. 提高线程的可管理性:线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分配、调优和监控。
  4. 提供更多更强大的功能:线程池具备可拓展性,允许开发人员向其中增加更多的功能。比如延时定时线程池ScheduledThreadPoolExecutor,就允许任务延期执行或定期执行。

Java 内置线程池

Java 异步编程——Java内置线程调度器(Executor 框架)一文中简单介绍了 Executor 框架以及两级调度模型,现在详细介绍 Executor 框架中相关的线程池类。

Executor、ExecutorService、ThreadPoolExecutor、Executors

Java 里面线程池的顶级接口是 Executor,顶层接口 Executor 提供了一种思想:将任务提交和任务执行进行解耦。用户无需关注如何创建线程,如何调度线程来执行任务,用户只需提供Runnable对象,将任务的运行逻辑提交到执行器(Executor)中,由Executor框架完成线程的调配和任务的执行部分。但是严格意义上讲 Executor 并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是 ExecutorService (一个 ExecutorService 对象代表一个线程池),这个接口里面声明了一系列管理线程和调度的方式,如:submit()、invokeAll()、invokeAny()、shutDown() 和 shutdownNow() 等,返回 Future 对象,以及可跟踪一个或多个异步任务执行状况返回 Future 的方法。而 ThreadPoolExecutor 是Java中最核心的一个线程池实现类,下面主要以 ThreadPoolExecutor 为例对线程池展开详细介绍。Executors 类,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了 ExecutorService 接口。
在这里插入图片描述

Java 内置线程池设计结构及执行机制

ThreadPoolExecutor 是Java中最核心的一个线程池实现类,这里介绍 ThreadPoolExecutor 线程池的运行机制,如下图所示:
在这里插入图片描述
执行机制(任务调度与线程调度)

  1. 在创建了线程池后,开始等待请求。
  2. 当调用 execute() 或 submit() 方法添加一个请求任务时,线程池会做出如下判断:
    1. 当任务数量少于 corePoolSize 线程池中的常驻核心线程数时,会自动创建 thread 来处理这些任务并加入线程池;
    2. 当添加任务数大于 corePoolSize 且少于 maximumPoolSize 时,不再创建线程,而是将这些任务放到阻塞队列中,等待被执行;
    3. 当阻塞队列满了之后,线程池中的线程数没有超过 maximumPoolSize 最大线程数(非核心线程数),则新建一个线程处理任务并加入到线程池中,从而加速处理阻塞队列;
    4. 当阻塞队列满了之后,且添加任务大于 maximmPoolSize 时,根据饱和策略决定是否容许继续向线程池中添加任务,默认的饱和策略是 AbortPolicy(直接丢弃)。
  3. 当一个线程完成任务时,它会从队列中取下一个任务来执行。
  4. 空闲的线程(非核心线程)会在到达 keepAliveTime 时间之后没有被使用的话就被回收(超过核心线程数的线程销毁,核心线程数以内的线程扔回池子待命)。所以线程池的所有任务完成后,线程池最终收缩只保留 corePoolSize 核心线程数的大小。
  5. <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值