図で比べるとこんなかんじ
schedule() - 指定した時間待機してから処理を実行する
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws Exception {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.schedule(() -> {
System.out.println("end!!");
service.shutdown();
System.exit(0);
}, 1, TimeUnit.SECONDS);
int count = 0;
while (true) {
Thread.sleep(100);
System.out.println((++count) * 100 + " ms");
}
}
}
実行結果
100 ms
200 ms
300 ms
400 ms
500 ms
600 ms
700 ms
800 ms
900 ms
1000 ms
end!!
scheduleAtFixedRate() - 一定時間ごとに処理を実行する
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String... args) throws Exception {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
AtomicInteger number = new AtomicInteger(0);
service.scheduleAtFixedRate(() -> {
int n = number.getAndIncrement();
System.out.println("begin(" + n + ")");
sleep(Math.max(1, 3-n));
System.out.println("end(" + n + ")");
}, 2, 2, TimeUnit.SECONDS);
int count = 0;
while (true) {
TimeUnit.SECONDS.sleep(1);
System.out.println((++count) + " s");
}
}
private static void sleep(long seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {}
}
}
- 第一引数の処理時間が、3秒→2秒→1秒→1秒→1秒...と徐々に短くなるように調整している
実行結果
1 s
begin(0)
2 s
3 s
4 s
end(0)
begin(1) ←直前の処理が終了するまで待機させられている
5 s
6 s
end(1)
begin(2)
7 s
end(2)
begin(3)
8 s
end(3)
9 s
begin(4)
10 s
end(4)
11 s
begin(5)
12 s
end(5)
13 s
begin(6)
14 s
end(6)
15 s
- 第二引数が、初回の待機時間。
- 第三引数が、二回目以降の待機時間。
-
第一引数の処理が完了しなくても、待機時間がすぎればガンガン処理が呼ばれる。(2020年3月11日、コメントで指摘があり修正) - 第三引数で指定した間隔で、第一引数に指定した処理が実行される
- ただし、第一引数の処理時間が第三引数で指定した時間よりも長くなると、次の処理は直前の処理が終了するまで待機させられる
- つまり、第一引数の処理が並列に実行されることはない
- 実行が待機させられた処理は、直前の処理が終了したら即座に実行される
scheduleWithFixedDelay() - 繰り返し処理の完了を待ってから一定時間待機を繰り返す
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Main {
private static int n = 0;
public static void main(String[] args) throws Exception {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleWithFixedDelay(() -> {
System.out.println("begin(" + n + ")");
sleep(1000);
System.out.println("end(" + n + ")");
n++;
}, 2, 1, TimeUnit.SECONDS);
int count = 0;
while (true) {
sleep(1000);
System.out.println((++count) + " s");
}
}
private static void sleep(long ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {}
}
}
実行結果
1 s
2 s
begin(0)
3 s
end(0)
4 s
begin(1)
5 s
end(1)
6 s
begin(2)
7 s
end(2)
8 s
begin(3)
9 s
end(3)
10 s
- 第二引数が、初回の待機時間。
- 第一引数の処理の完了を待機してから、第三引数で指定した時間待機して、次の処理を実行する