一,前言
ScheduledExecutorService 可以根据时间需要对线程进行调度。如果任务遇到异常,那么后续的所有子任务都会停止调度,因此,须保证异常被即时处理,为周期性任务的稳定调度提供条件。
二,主要方法
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
schedule()
会在给定时间对任务进行一次调度。
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period,TimeUnit unit);
scheduleAtFixedRate()
按固定周期对任务进行调度,任务调度的频率是一定的。
固定周期 (n秒),下一任务开始时间计算:
①上一任务执行时间 < 固定周期n秒:下一任务开始时间 = 上一任务开始执行时间 + 周期 (n秒);
②上一任务执行时间 > 固定周期:下一任务开始时间 = 上一任务开始执行时间 + 上一任务执行时长。
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,long delay,TimeUnit unit);
scheduleWithFixedDelay()
按固定延迟周期对任务进行调度。
固定周期 (n秒),下一任务开始时间计算:
下一任务执行时间 = 上一任务开始执行时间 + 上一任务执行时长 + 固定周期 (n秒)。
三,使用案例
import cn.hutool.core.date.DateUtil;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolDemo {
public static void main(String[] args) {
ScheduledExecutorService ses = Executors.newScheduledThreadPool(10);
System.out.println("开始时间:" + DateUtil.formatDateTime(new Date()));
ses.scheduleAtFixedRate(new FixedRate1Test(), 0, 2, TimeUnit.SECONDS);
ses.scheduleAtFixedRate(new FixedRate2Test(), 0, 2, TimeUnit.SECONDS);
ses.scheduleWithFixedDelay(new FixedDealyTest(), 0, 2, TimeUnit.SECONDS);
ses.schedule(new ScheduleTest(), 2, TimeUnit.SECONDS);
}
public static class FixedRate1Test implements Runnable {
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("A: " + DateUtil.formatDateTime(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class FixedRate2Test implements Runnable {
@Override
public void run() {
try {
Thread.sleep(4000);
System.out.println("B: " + DateUtil.formatDateTime(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class FixedDealyTest implements Runnable {
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("C: " + DateUtil.formatDateTime(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class ScheduleTest implements Runnable {
@Override
public void run() {
System.out.println("D: " + DateUtil.formatDateTime(new Date()));
}
}
}
执行结果:
开始时间:2021-05-12 17:33:27
A: 2021-05-12 17:33:28
C: 2021-05-12 17:33:28
D: 2021-05-12 17:33:29
A: 2021-05-12 17:33:30
B: 2021-05-12 17:33:31
C: 2021-05-12 17:33:31
A: 2021-05-12 17:33:32
A: 2021-05-12 17:33:34
C: 2021-05-12 17:33:34
B: 2021-05-12 17:33:35
A: 2021-05-12 17:33:36
C: 2021-05-12 17:33:37
案例中,固定周期为2秒
scheduleAtFixedRate 测试1:FixedRate1Test:任务执行时间 1s,少于 周期 2秒,所以可以看到它(A)每隔周期 2秒执行一次;
scheduleAtFixedRate 测试2:FixedRate2Test:任务执行时间 4s,大于 周期 2秒,所以可以看到它(B)每隔周期 4秒执行一次;
scheduleWithFixedDelay 测试:FixedDealyTest:任务执行时间 1s,可以看到它(C)每隔周期 3秒执行一次;
schedule 测试:ScheduleTest:可以看到它(D)在开始时间延迟周期 2秒后执行;
评论区