scheduledexecutorservice 只执行一次_Java8源码分析:ScheduledExecutorService周期任务停止执行原因...

一、概述

  • ScheduledExecutorService继承于ExecutorService,主要提供任务的延迟和周期性执行的功能。其主要提供了schedule,scheduleAtFixedRate,scheduleWithFixedDelay三个方法,分别用于延迟执行任务,以特定频率周期性执行任务,以特定延迟周期性执行任务。
0ec3a730c88f85d2489e228d6bedadcb.png
  1. schedule:延迟delay时间执行一次;
  2. scheduleAtFixedRate:以给定的频率周期性执行,分别为initialDelay,initialDelay+period,initialDelay+2period,…,如果出现越界,如initialDelay+period时线程执行时间过长,超过了initialDelay+2period,则下一次从initialDelay+3*period开始执行,不会出现重叠问题,即遵循happen-before原则。如果线程池存在多个线程,则每次执行可能在不同的线程当中。周期性执行的command如果在执行期间抛了异常而没有捕获,则之后不会继续执行该command,即不会再周期性执行了,scheduleWithFixedDelay也是一样;
  3. scheduleWithFixedDelay:每次执行相隔delay时间,即第一次延迟initialDelay执行,执行完之后等待delay时间后执行第二次,依次类推,跟每次执行的时间无关。

二、周期性任务停止执行的原因

  • 方法scheduleAtFixedRate和scheduleWithFixedDelay在执行周期性Runnable任务过程当中,如果Runnable任务自身的run方法抛了异常而没有捕获,则会导致scheduleAtFixedRate和scheduleWithFixedDelay不会继续周期性执行该任务了,即该任务停止执行。实现原理如下:

1.ScheduledThreadPoolExecutor内部定义了一个内部类ScheduledFutureTask,ScheduledFutureTask继承于FutureTask,由该内部类来对任务进行封装,提供周期性执行的功能。

34795f8ca72e0ba8c6bcdae915023501.png

2.ScheduledFutureTask的run方法实现如下:主要在runAndReset方法中执行该周期性任务,如果执行成功返回true,则调用setNextRunTime设置下次执行时间;如果该方法返回false,则不再调用setNextRunTime设置下次执行时间,故该周期性任务停止执行。

dbf6e587daaa02e92196f13501b95ded.png

3.runAndReset的实现:执行任务,在成功执行时,则ran为true,state的值还是NEW,故方法返回值为true。但是如果在执行过程中,即c.call()调用时,出现了异常,则ran设置为false,并在catch块中通过setExeception处理。在setException中将state更新为了EXCEPTIONAL,同时唤醒等待该任务结果的线程,则最终的ran && s == NEW为false,导致runAndReset方法返回false,由上面run的分析可知,该周期任务不再执行。

1c2a0b0f8569bacbd3d7b234303bbc12.png

4.setException方法的定义如下:将state更新为EXCEPTIONAL,以便阻塞等待该任务执行结果的线程知道发生了异常,同时调用finishCompletion唤醒这些等待线程。

d3868b2cd454cd07a30c842a00efecd4.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值