ScheduledExecutorService的简单使用和scheduleAtFixedRate和scheduleWithFixedDelay区别
JAVA用于执行周期性任务的线程池:ScheduledExecutorService
ScheduledExecutorService的继承关系
执行周期性任务的两个方法
- scheduleAtFixedRate
- scheduleWithFixedDelay
方法介绍
1、scheduleAtFixedRate
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
- Runnable command 任务对象
- long initialDelay 任务开始执行的延迟时间
- long period 任务执行的间隔周期 例如 1s 10min 1h 等
- TimeUnit unit 任务执行周期的时间单位
示例:每隔1s打印一次hello world
@Slf4j
public class ThreadTest {
private static ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1);
public static void main(String[] args) {
log.info("task begin");
executorService.scheduleAtFixedRate(() -> {
log.info("hello world !");
}, 1, 1, TimeUnit.SECONDS);
}
}
运行结果:
2、scheduleWithFixedDelay
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
- Runnable command 任务对象
- long initialDelay 任务开始执行的延迟时间
- long period 任务执行的间隔周期 例如 1s 10min 1h 等
- TimeUnit unit 任务执行周期的时间单位
示例:每隔1s打印一次hello world
@Slf4j
public class ThreadTest {
private static ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1);
public static void main(String[] args) {
log.info("task begin");
executorService.scheduleWithFixedDelay(() -> {
log.info("hello world !");
}, 1, 1, TimeUnit.SECONDS);
}
}
运行结果:
区别与联系
-
两个方法都可以执行周期性的任务,在任务执行时间比较短,小于任务执行周期的时候,两者几乎没什么区别
-
当任务执行时间大于任务执行周期的时候,如下案例
我们让两个方法执行周期都是1s,任务执行时间变成2s
@Slf4j
public class ThreadTest {
private static ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1);
public static void main(String[] args) {
log.info("task begin");
executorService.scheduleAtFixedRate(() -> {
log.info("hello world !");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, 1, 1, TimeUnit.SECONDS);
}
}
执行结果:
@Slf4j
public class ThreadTest {
private static ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1);
public static void main(String[] args) {
log.info("task begin");
executorService.scheduleWithFixedDelay(() -> {
log.info("hello world !");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, 1, 1, TimeUnit.SECONDS);
}
}
执行结果:
总结:
- 可以看到 scheduleAtFixedRate 是从上个任务开始的时间计时,如果任务的执行时间小于任务的周期,则任务周期到了之后立即执行下个任务,如果执行任务的时间大于任务的执行周期,则继续等待第一个任务执行完毕之后,在继续下一个任务
- scheduleWithFixedDelay是等待上一个任务结束时开始计时