一、背景
在开发中经常会遇到一些需要周期性重复执行某个任务。这里我们可以使用java自身提供的ScheduledExecutorService来实现。我们通常会使用其中的两个方法,scheduleAtFixedRate和scheduleWithFixedDelay。
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) 创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。
scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。
这么说可能不太清晰,我们用一个例子来说明一下:
我们来启动5个任务。
其中,第三个启动的任务执行时间为10s,其他任务执行时间不做控制。
当调用scheduledThreadPoolExecutor.scheduleAtFixedRate(command, 1, 2, TimeUnit.SECONDS);时表示1s后开始执行任务,2秒后启动第二个任务,倘若上一个任务还未结束,则等待上一个任务完成,完成后直接启动第二个任务。第一次出现index=3的时间和第二次出现index=3的时间为10s,因为第一次出现3的线程需要执行10s才能返回,此时已经超过了2s的等待时间,以此类推。以下是运行结果
当调用scheduledThreadPoolExecutor.scheduleWithFixedDelay(command, 1, 5, TimeUnit.SECONDS);时表示1s后开始执行任务,2秒后启动第二个任务,倘若上一个任务还未结束,则等待上一个任务完成,完成后再等待5s启动第二个任务,第一次出现3的时间和第二次出现3的时间为15s,因为第一次出现3的线程需要执行10s才能返回,等第一个线程返回后,过5s开始执行第二个线程,以此类推。以下是运行结果:
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class ScheduledExecutorServiceTest {
private static final AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args) {
int count = 0;
ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(2);
for(int i=0;i<5;i++) {
Command command = new Command(i);
//scheduledThreadPoolExecutor.scheduleAtFixedRate(command, 1, 2, TimeUnit.SECONDS);
scheduledThreadPoolExecutor.scheduleWithFixedDelay(command, 1, 5, TimeUnit.SECONDS);
}
}
static class Command implements Runnable {
private int index;
public Command(int index) {
this.index = index;
}
public void run() {
if(index==3) {
try {
System.out.println("第"+count.incrementAndGet()+"次出现"+index+"的时间为===="+System.currentTimeMillis()/1000);
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}