Javaでコードの実行を遅らせる方法

1. 前書き

Javaプログラムでは、操作に遅延または一時停止が追加されるのが比較的一般的です。 これは、タスクのペーシングや、別のタスクが完了するまで実行を一時停止するのに役立ちます。
このチュートリアルでは、Javaで遅延を実装する2つの方法について説明します。

2. _Thread_ベースのアプローチ

  • Javaプログラムが実行されると、ホストマシンで実行されるプロセス*が生成されます。 このプロセスには、プログラムが実行される少なくとも1つのスレッド(メインスレッド)が含まれます。 さらに、Javaはmultithreadingを有効にします。これにより、アプリケーションは、メインスレッドに対して並列または非同期で実行される新しいスレッドを作成できます。

2.1. _Thread.sleep_の使用

Javaで一時停止する手っ取り早い方法は、現在のスレッドに指定された時間だけスリープさせることです。 これは、_Thread.sleep(milliseconds)_を使用して実行できます。
try {
    Thread.sleep(secondsToSleep * 1000);
} catch (InterruptedException ie) {
    Thread.currentThread().interrupt();
}
*別のスレッドがスリープ中のスレッドを中断する場合に_sleep_メソッドをtry / catchブロックにラップすることをお勧めします。*この場合、_InterruptedException_をキャッチし、現在のスレッドを明示的に中断して、後でキャッチして処理できるようにします。 これはマルチスレッドプログラムではより重要ですが、後で他のスレッドを追加する場合に備えて、シングルスレッドプログラムでは依然として優れたプラクティスです。

2.2. _TimeUnit.sleep_の使用

*読みやすくするために、_TimeUnit.XXX.sleep(y)_を使用できます。_XXX_はスリープする時間単位(_SECONDS_、DS_MINUTES_など)、_y_はスリープする単位の数です。*これ舞台裏で_Thread.sleep_を使用します。 _TimeUnit_構文の例を次に示します。
try {
    TimeUnit.SECONDS.sleep(secondsToSleep);
} catch (InterruptedException ie) {
    Thread.currentThread().interrupt();
}
ただし、*これらのスレッドベースのメソッドを使用することにはいくつかの欠点があります*:
  • 睡眠時間は、特に小さいを使用する場合、正確に正確ではありません
    ミリ秒やナノ秒などの時間増分

  • ループの内側で使用すると、ループ間でスリープがわずかにドリフトします
    他のコード実行による反復。多数の反復後に実行時間が不正確になる可能性があります。

3. _ExecutorService_ベースのアプローチ

Javaはlink:/java-executor-service-tutorial[_ScheduledExecutorService_]インターフェイスを提供します。これは、より堅牢で正確なソリューションです。 このインターフェイスは、指定された遅延後または一定の時間間隔で1回実行するようにコードをスケジュールできます。
遅延後にコードを1回実行するには、_schedule_メソッドを使用できます。
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

executorService.schedule(Classname::someTask, delayInSeconds, TimeUnit.SECONDS);
_Classname

someTask_の部分は、遅延後に実行するメソッドを指定する場所です。

  • _someTask_は、実行するメソッドの名前です

  • _Classname_は、_someTask_を含むクラスの名前です
    方法

    一定の時間間隔でタスクを実行するには、_scheduleAtFixedRate_メソッドを使用できます。
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

executorService.scheduleAtFixedRate(Classname::someTask, 0, delayInSeconds, TimeUnit.SECONDS);
これは_someTask_メソッドを繰り返し呼び出し、各呼び出しの間に_delayInSeconds_を一時停止します。
_ScheduledExecutorService_メソッドは、より多くのタイミングオプションを許可することに加えて、ドリフトの問題を防ぐため、より正確な時間間隔を生成します。

4. 結論

この記事では、Javaプログラムで遅延を作成する2つの方法について説明しました。
この記事の完全なコードは、https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-concurrency-basic [Github上]にあります。 これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。