Java~学习Executor框架, 了解ThreadPoolExecutor和ScheduledThreadPoolExecutor

  • Executor是一个接口它是Executor框架的基础,它将任务的提交与任务的执行分离开 来。

  • ThreadPoolExecutor是线程池的核心实现类,用来执行被提交的任务

  • ScheduledThreadPoolExecutor是一个实现类,可以在给定的延迟后运行命令,或者定期执 行命令。ScheduledThreadPoolExecutor比Timer更灵活,功能更强大。

  • Future接口和实现Future接口的FutureTask类,代表异步计算的结果。

  • Runnable接口和Callable接口的实现类,都可以被ThreadPoolExecutor或Scheduled- ThreadPoolExecutor执行。

Executor框架的成员

ThreadPoolExecutor
  • ThreadPoolExecutor通常使用工厂类Executors(也就是说Executors是一个工厂, 其内部有很多车间, 其中一个就是生产ThreadPoolExecutor的)来创建。Executors可以创建3种类型的 ThreadPoolExecutor、SingleThreadExecutor、FixedThreadPool和CachedThreadPool。
  1. FixedThreadPool。

FixedThreadPool适用于为了满足资源管理的需求,而需要限制当前线程数量的应用场 景,它适用于负载比较重的服务器。

  • 原理就是

(1) 如果当前运行的线程数少于corePoolSize(核心线程的数量, 也就是允许多少个线程处于空闲状态),则创建新线程来执行任务。

(2) 在线程池完成预热之后(当前运行的线程数等于corePoolSize),将任务加入 LinkedBlockingQueue。

(3)一个线程执行完任务后,会在循环中反复从LinkedBlockingQueue获取任务来执行。 FixedThreadPool使用无界队列LinkedBlockingQueue作为线程池的工作队列(队列的容量为 Integer.MAX_VALUE)

  1. SingleThreadExecutor。

SingleThreadExecutor适用于需要保证顺序地执行各个任务;并且在任意时间点,不会有多个线程是活动的应用场景。

SingleThreadExecutor的corePoolSize和maximumPoolSize(最大线程的数量)被设置为1。其他参数与 FixedThreadPool相同。SingleThreadExecutor使用无界队列LinkedBlockingQueue作为线程池的工 作队列(队列的容量为Integer.MAX_VALUE)

  1. CachedThreadPool。
  • CachedThreadPool是大小无界的线程池,适用于执行很多的短期异步任务的小程序,或者 是负载较轻的服务器。

  • CachedThreadPool的corePoolSize被设置为0,即corePool为空;maximumPoolSize被设置为 Integer.MAX_VALUE,即maximumPool是无界的。这里把keepAliveTime设置为60L,意味着 CachedThreadPool中的空闲线程等待新任务的最长时间为60秒,空闲线程超过60秒后将会被 终止。

  • CachedThreadPool使用没有容量的SynchronousQueue作为线程池的工作队列,但 CachedThreadPool的maximumPool是无界的。这意味着,如果主线程提交任务的速度高于 maximumPool中线程处理任务的速度时,CachedThreadPool会不断创建新线程。极端情况下, CachedThreadPool会因为创建过多线程而耗尽CPU和内存资源。

ScheduledThreadPoolExecutor
  • ScheduledThreadPoolExecutor通常使用工厂类Executors来创建。Executors可以创建2种类 型的ScheduledThreadPoolExecutor。
  1. ScheduledThreadPoolExecutor。
  • 包含若干个线程的ScheduledThreadPoolExecutor。适用于需要多个后台线程执行周期任务或者延时执行,同时为了满足资源管理的需求而需要限制后台线程的数量的应用场景。

  • 使用DelayQueue作为任务队列。DelayQueue封装了一个PriorityQueue,这个PriorityQueue会对队列中的Scheduled- FutureTask进行排序。排序时,time小的排在前面(时间早的任务将被先执行)。如果两个 ScheduledFutureTask的time相同,就比较sequenceNumber,sequenceNumber小的排在前面(也就 是说,如果两个任务的执行时间相同,那么先提交的任务将被先执行)。

  1. SingleThreadScheduledExecutor。

只包含一个线程的ScheduledThreadPoolExecutor。 适用于需要单个后台线程执行周期任务或者延迟任务,同时需要保证顺序地执行各个任务的应用场景。

Future接口
  • Future接口和实现Future接口的FutureTask类用来表示异步计算的结果。

当我们把Runnable 接口或Callable接口的实现类提交(submit)给ThreadPoolExecutor或 ScheduledThreadPoolExecutor时,ThreadPoolExecutor或ScheduledThreadPoolExecutor会向我们 返回一个FutureTask对象。

  • FutureTask可以处于下面3种状态。

  • 1)未启动。FutureTask.run()方法还没有被执行之前,FutureTask处于未启动状态。当创建一 个FutureTask,且没有执行FutureTask.run()方法之前,这个FutureTask处于未启动状态。

  • 2)已启动。FutureTask.run()方法被执行的过程中,FutureTask处于已启动状态。

  • 3)已完成。FutureTask.run()方法执行完后正常结束,或被取消(FutureTask.cancel(…)),或 执行FutureTask.run()方法时抛出异常而异常结束,FutureTask处于已完成状态。

  • 当FutureTask处于未启动或已启动状态时,执行FutureTask.get()方法将导致调用线程阻塞;当FutureTask处于已完成状态时,执行FutureTask.get()方法将导致调用线程立即返回结果或抛出异常。

  • FutureTask的实现基于AQS。java.util.concurrent中 的很多可阻塞类(比如ReentrantLock)都是基于AQS来实现的。AQS是一个同步框架,它提供通用机制来原子性管理同步状态、阻塞和唤醒线程,以及维护被阻塞线程的队列

  • 每一个基于AQS实现的同步器都会包含两种类型的操作,至少一个acquire操作。这个操作阻塞调用线程,除非/直到AQS的状态允许这个线程继续 执行。FutureTask的acquire操作为get()/get(long timeout,TimeUnit unit)方法调用。 至少一个release操作。这个操作改变AQS的状态,改变后的状态可允许一个或多个阻塞 线程被解除阻塞。FutureTask的release操作包括run()方法和cancel(…)方法。

  • 基于“复合优先于继承”的原则,FutureTask声明了一个内部私有的继承于AQS的子类 Sync,对FutureTask所有公有方法的调用都会委托给这个内部子类

Runnable接口和Callable接口
  • Runnable接口和Callable接口的实现类,都可以被ThreadPoolExecutor或Scheduled- ThreadPoolExecutor执行。
  • 它们之间的区别是Runnable不会返回结果,而Callable可以返回结 果。 除了可以自己创建实现Callable接口的对象外,还可以使用工厂类Executors来把一个 Runnable包装成一个Callable。 下面是Executors提供的,把一个Runnable包装成一个Callable的API。
    public static Callable callable(Runnable task)
  • 提交给 ThreadPoolExecutor或ScheduledThreadPoolExecutor执行时,submit(…)会向我们返回一个 FutureTask对象。我们可以执行FutureTask.get()方法来等待任务执行完成。当任务成功完成后 FutureTask.get()将返回该任务的结果。

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618164986)

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 25
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值