こんにちは。「Javaを復習する初心者」です。
今回はスレッドをスリープさせる方法を使ってみました。
スレッドをスリープさせる方法を調べた結果、2つあるのが分かりました。Thread#sleep()メソッド、TimeUnit#sleep()メソッドです。以下ではそれぞれを使ってみます。
Thread#sleep()
スレッドをスリープさせる方法は一つ目はThread#sleep()メソッドを使うことです。引数にはミリ秒を指定します。例えば、以下のプログラムではスレッド内で5秒スリープしています。
ソース
Thread t1 = new Thread(() -> {
long start, end;
start = System.currentTimeMillis();
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
end = System.currentTimeMillis();
System.out.println(end -start);
});
t1.start();
実効結果は以下です。
結果
500
System#currentTimeMillis()メソッドを使うとミリ秒で表される現在の時間を取得できます。開始と終了の差を出力しています。上記のように500ミリ秒と出力されました。スレッドが5秒スリープしたということです。
TimeUnit#sleep()
スレッドをスリープさせる別の方法はTimeUnit列挙型sleep()メソッドを使うことです。このメソッドはstaticではありません。なのでTimeUnitの定数を使う必要があるようです。
TimeUnitには以下の定数が定義されています。全て時間単位を表します。
定数 | 時間単位 |
---|---|
DAYS | 24時間 |
HOURS | 60分 |
MICROSECONDS | ミリ秒の1000分の1 |
MILLISECONDS | 秒の1000分の1 |
MINUTES | 60秒 |
NANOSECONDS | マイクロ秒の1000分の1 |
SECONDS | 1秒 |
以下、TimeUnit.SECONDSを使い、sleep()メソッドを呼び出してみました。
ソース
Thread t1 = new Thread(() -> {
long start, end;
start = System.currentTimeMillis();
try {
TimeUnit.SECONDS.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
end = System.currentTimeMillis();
System.out.println(end -start);
});
t1.start();
結果
10001
上記の通り、約10秒となりました。
TimeUnit#sleep()メソッドについて、API仕様書には「Thread.sleepを実行します」と書いてあります。ソースを見ると確かに「Thread.sleep(ms, ns);」という行がありました。Thread.sleepはInterruptedExceptionをスロー宣言しているメソッドですが、try-catch文はありませんでした。その代わり、TimeUnit#sleep()メソッドにInterruptedExceptionのスロー宣言がありました。そのため、上記のプログラムではtry-catch文を書いています。
「Thread.sleep(ms, ns);」についてですが、第一引数に負の数が指定されてた場合、IllegalArgumentExceptionがすろーされるようになってます。TimeUnit#sleep()側ではif文を使っていて、引数がゼロまたはそれより小さい場合はスリープしないようになっています。
TimeUnit#sleep()メソッドの内部ではtoMillis()メソッドが呼び出されます。TimeUnit.SECONDSに対して、sleepメソッドを呼び出した場合、SECONDS.toMillis()が呼び出される仕組みです。ソースを追ってみると、NANOSECONDS~DAYSまでtoMillisメソッドの定義が書いてある箇所があります。それぞれ、static long x(long d, long m, long over)というメソッドを呼び出しているのですが、引数を調節して、統一的に変換できるように記述されてました。