Java の ScheduledExecutorService インターフェイスは、スレッド プールに基づいて設計されたスケジュール タスク クラスです。スケジュールされた各タスクは、実行のためにスレッド プール内のスレッドに割り当てられます。つまり、タスクは互いに影響を与えることなく同時に実行されます。
実装クラスの 1 つは ScheduledThreadPoolExecutor です。ScheduledThreadPoolExecutor の UML クラス図の関係は次のとおりです。
(1)>ScheduledThreadPoolExecutor は、ScheduledExecutorService インターフェイスを実装し、いくつかのタイミング タスク処理メソッドを実装します。
(2)>ScheduledThreadPoolExecutor は ThreadPoolExecutor を継承し、スレッド プールを介してタスクを管理およびスケジュールできます。
以下では、ScheduledThreadPoolExecutor で ScheduledExecutorService インターフェイスを実装するために最も一般的に使用される 2 つのスケジューリング メソッド、ScheduleAtFixedRate および ScheduleWithFixedDelay を紹介します。
1. scheduleAtFixedRate 方法
1: 方法の紹介
scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit)
上記の 4 つのパラメーターについて説明します。
最初のコマンド パラメーターはタスク インスタンス、
2 番目の initialDelay パラメーターは初期化遅延時間、
3 番目の period パラメーターはインターバル時間、
4 番目の unit パラメーターは時間単位です。
2:コード例
(1):タスクインスタンスcommodの実行時間がインターバル時間未満の場合
public class TestExecutor {
private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
public static void main(String[] args) {
}
/**
* 进行scheduleAtFixedRate测试
*/
public static void testFixedRate(){
executor.scheduleAtFixedRate(new myRun(), 5, 5, TimeUnit.SECONDS);
}
static class myRun implements Runnable{
@Override
public void run() {
System.out.println("----测试开始--------"+ new Date().toLocaleString());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("---休眠3秒后, 处理结束--------"+new Date().toLocaleString());
}
}
}
操作結果:
----测试开始--------2017-10-11 11:38:38 #第一次执行
---休眠3秒后, 处理结束--------2017-10-11 11:38:41 #第一次任务处理,花费3秒
#第二次执行时间是第一次时间 + period 即38 + 5 = 43;
----测试开始--------2017-10-11 11:38:43
---休眠3秒后, 处理结束--------2017-10-11 11:38:46
----测试开始--------2017-10-11 11:38:48
---休眠3秒后, 处理结束--------2017-10-11 11:38:51
----测试开始--------2017-10-11 11:38:53
(2):タスクインスタンスcommodの実行時間がインターバル時間より長い場合、
Thread.sleep(3000);をThread.sleep(6000);に変更して実行すると実行結果が表示されます!
操作結果:
----测试开始--------2017-10-11 11:41:22 #第一次执行时间
---休眠3秒后, 处理结束--------2017-10-11 11:41:28 # 任务处理6秒,即 22+6 = 28
#第二次执行时间 == 上一次处理结束时间,因为任务处理时间大于period间隔时间
----测试开始--------2017-10-11 11:41:28
---休眠3秒后, 处理结束--------2017-10-11 11:41:34
----测试开始--------2017-10-11 11:41:34
3: 要約
ScheduleAtFixedRate 各実行時間は、最後のタスクの開始から遡った時間間隔です。(1 )
コマンドの実行時間がピリオド未満の場合、各実行時間が initialDelay、initialDelay + ピリオド、initialDelay + 2*ピリオド、...;
(2) コマンドの実行時間が期間より大きい場合、コマンドが実行され、すぐに次のタスクが実行されます。以下は、予想される時間間隔に従って次のタスクが実行されないことを意味します。各実行時間は次のとおりです。
taskExecutorTIme はタスクの実行時間です!
二、scheduleWithFixedDelay
1: 方法の紹介
scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit
上記の 4 つのパラメーターについて説明します。
最初のコマンド パラメーターはタスク インスタンス、
2 番目の initialDelay パラメーターは初期遅延時間、
3 番目の遅延パラメーターは遅延間隔時間、
4 番目の単位パラメーターは時間単位です。
2: コード例
(1):タスクインスタンスcommodの実行時間が遅延間隔time delay未満の場合
public class TestExecutor {
private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
public static void main(String[] args) {
testFixedDelay();
}
public static void testFixedDelay(){
executor.scheduleWithFixedDelay(new myRun(), 5, 5, TimeUnit.SECONDS);
}
static class myRun implements Runnable{
@Override
public void run() {
System.out.println("----测试开始--------"+ new Date().toLocaleString());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("---休眠3秒后, 处理结束--------"+new Date().toLocaleString());
}
}
}
操作結果:
----测试开始--------2017-10-11 11:59:02 #第一次执行时间
---休眠3秒后, 处理结束--------2017-10-11 11:59:05 #任务处理的时间,3秒
#第二次执行的时间 == 第一次任务开始时间+任务处理时间+delay延迟时间
#即 10 == 02 + 3秒 + 5秒
----测试开始--------2017-10-11 11:59:10
---休眠3秒后, 处理结束--------2017-10-11 11:59:13
----测试开始--------2017-10-11 11:59:18
---休眠3秒后, 处理结束--------2017-10-11 11:59:21
(2): タスク インスタンス commod の実行時間が遅延間隔 delay より大きい場合、
Thread.sleep(3000); を Thread.sleep(6000); に変更し
、実行結果:
----测试开始--------2017-10-11 12:02:48 #第一次任务执行开始时间
---休眠6秒后, 处理结束--------2017-10-11 12:02:54 #任务处理的时间 ,6秒
#第二次任务执行开始时间 == 第一次任务执行开始时间 + 任务处理的时间 + delay延迟时间
#即 59 == 48 + 6 + 5
----测试开始--------2017-10-11 12:02:59
---休眠6秒后, 处理结束--------2017-10-11 12:03:05
----测试开始--------2017-10-11 12:03:10
3:まとめ
タスクコマンドの実行時間がいくら長くても、次のタスクの実行時間は、前のタスクの実行後、遅延間隔遅延時間待ってから次のタスクを実行することです。
ScheduleWithFixedDelay の各実行時間は、最後のタスクの終了から時間間隔だけ押し戻されます。つまり、各実行時間は、initialDelay、initialDelay+executeTime+delay、initialDelay+2 executeTime +2 delayです。
参考
https://www.ibm.com/developerworks/cn/java/j-lo-taskschedule/