Java8之ScheduledThreadPoolExecutor实现原理

本文深入探讨了ScheduledThreadPoolExecutor的工作原理,它如何实现定时任务,以及其构造方法、任务提交过程和ScheduledFutureTask的角色。ScheduledFutureTask在任务执行后调整执行时间并重新加入工作队列,而DelayedWorkQueue作为一个特殊的任务队列,确保任务在设定时间到达后执行。文章还分析了构造方法、任务提交和ScheduledFutureTask的run方法及其参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ScheduledThreadPoolExecutor是一个可实现定时任务的线程池,ScheduledThreadPoolExecutor内的任务既可以在设定的时间到达时执行一次,也可以相隔固定时间周期执行。

ScheduledThreadPoolExecutor继承自ThreadPoolExecutor,关于ThreadPoolExecutor的原理可参考:

Java8之ThreadPoolExecutor实现原理

ScheduledThreadPoolExecutor相比较于ThreadPoolExecutor,只多了四个提交任务的方法,这四个方法实现自ScheduledExecutorService,继承自ThreadPoolExecutor的execute和submit方法都调用了自己的schedule方法

  1. 第一个schedule的任务是runnable,不支持获取返回值,会在指定延迟时间之后执行一次
  2. 第二个schedule的任务是callable,可获取返回值,会在指定延迟时间之后执行一次
  3. scheduleAtFixedRate的任务为runnable,不支持获取返回值,会在指定延迟时间后执行一次,之后按设定好的间隔时间重复执行
  4. scheduleWithFixedDelay的任务为runnable,不支持获取返回值,会在指定延迟时间后执行一次,并在执行完成时间的基础上按间隔时间周期执行

后两个方法可能理解起来不是很清楚,简单点说,scheduleAtFixedRate的下一次任务的执行时间为:法定的任务开始时间(并不是任务真正开始执行的时间,因为线程池是在任务执行完成后再计算下一次的开始时间,此时计算出的开始时间可能已经小于现在的时间了,当这个任务执行的时候,真实的执行时间肯定比设定好的时间大)+间隔;scheduleWithFixedDelay的下一次任务执行时间为:任务结束时间+间隔。

我们将scheduleAtFixedRate演示一下,正常情况如下,其中0、5、15、20就是法定的任务开始时间

不正常的情况如下

实现原理

ScheduledThreadPoolExecutor之所以能够实现上述的定时功能,本质上是通过两点实现的:

1.将任务包装在ScheduledFutureTask内。ScheduledFutureTask相当于原始任务的代理,在执行原始任务之后会视情况将任务的执行时间修改后再加入工作队列

2.使用了DelayedWorkQueue作为任务队列。DelayedWorkQueue内部是一个ScheduledFutureTask的数组,queue的功能类似于DelayQueue,在设定的时间到达时才能取出队列中的元素。

下面我们基于以上两点来分析源码。

1.构造方法

以最后一个构造函数为例,四个构造方法都调用了父类(ThreadPoolExecutor)的构造方法,最大线程数都设置为int最大值,线程存活时间都为0,工作队列都为DelayedWorkQueue

    public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory,
                                       RejectedExecutionHandler handler) {
        //最大线程数为int最大值,线程空转时间为0,使用DelayedWorkQueue作为工作队列
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue(), threadFactory, handler);
    }

2.任务提交

普通的schedule方法会将间隔时间设为

ScheduledThreadPoolExecutorJava 中的一个线程池实现,它可以根据指定的延迟时间或定时周期执行任务。其原理主要包括以下几个方面: 1. 线程池管理:ScheduledThreadPoolExecutor 内部维护一个线程池,其中包含多个工作线程。这些工作线程可以并行执行提交的任务。 2. 任务队列:ScheduledThreadPoolExecutor 使用一个任务队列来存储提交的任务。当任务被提交时,会先进入任务队列中等待执行。 3. 任务调度:ScheduledThreadPoolExecutor 使用一个调度器来控制任务的执行时间。调度器会根据任务的延迟时间或定时周期,将任务从任务队列中取出,并分配给空闲的工作线程执行。 4. 线程池调度策略:ScheduledThreadPoolExecutor 提供了不同的调度策略,可以根据需要选择合适的策略。见的调度策略包括延迟执行、周期性执行、固定延迟执行等。 5. 线程池管理和任务调度的协调:ScheduledThreadPoolExecutor 通过线程池管理和任务调度的协调,实现了对延迟执行或定时周期执行任务的支持。它会根据需要动态地创建、销毁工作线程,并将任务分配给这些工作线程执行。 总之,ScheduledThreadPoolExecutor 通过线程池管理和任务调度的机制,实现了对延迟执行或定时周期执行任务的支持。这使得开发者可以方便地控制任务的执行时间,并且可以充分利用系统资源来提高任务执行的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值