Java : Thread.sleep の代わりに TimeUnit.sleep を使う
スレッドの処理を一時的に止めるには、ミリ秒を指定する Thread.sleep がよく使われます。
実は TimeUnit クラスにも sleep メソッドがあります。
TimeUnit を使うと、Thread.sleep よりも少しだけソースコードの可読性がよくなります。
本記事では、そんなちょっとした TIPS をご紹介します。
補足
- Java 19 で、Duration をパラメータとする Thread.sleep(Duration duration) メソッドが追加されました。
もし Java 19 以降を使うのであれば、TimeUnit.sleep ではなく Thread.sleep(Duration duration) でもよいかもしれません。
Thread.sleep(long millis)
Thread.sleep は、指定した時間(ミリ秒単位)の間、一時的にスレッドを停止します。
例えば、5秒止めるには次のようにします。(5秒 = 5000ミリ秒です)
final var start = System.nanoTime();
Thread.sleep(5000);
final var end = System.nanoTime();
// 5.009705 秒
System.out.printf("%f 秒%n", (end - start) / 1000000000.0);
多少の誤差はありますが、無事、5秒停止することができました。
補足
- System.nanoTime は、処理時間を計るために使います。
ナノ秒単位の値を返すので、1000000000 で割ることにより秒に変換しています。
普段から Java を使っている人であれば、Thread.sleep(5000) を見て、5秒止めるんだな、とすぐに分かるかもしれません。
ひさしぶりに Java のコードを見た人が、あれ sleep の単位ってなんだっけ? となることもあるでしょう。
その場合は API仕様を確認することになります。その分手間になるわけですね。
コードを読んでいて、あれ?と思うことがあるのは、それは可読性が少し低いコードです。
可読性をよくするためにコメントを入れることもあるかもしれません。
// 5秒停止させる。
Thread.sleep(5000);
ただ、個人的にはこれは 過剰なコメント だと思います。
もっと良い方法は、TimeUnit を使うことです。
TimeUnit.sleep
TimeUnit は、時間の単位を表す列挙型です。
列挙子には
- 日 (DAYS)
- 時 (HOURS)
- 分 (MINUTES)
- 秒 (SECONDS)
- ミリ秒 (MILLISECONDS)
- マイクロ秒 (MICROSECONDS)
- ナノ秒 (NANOSECONDS)
があります。
TimeUnit は列挙型ですが、いくつかのユーティリティ・メソッドが用意されています。
sleep もその1つです。
それでは、TimeUnit を使って5秒止める例を見てみましょう。
final var start = System.nanoTime();
TimeUnit.SECONDS.sleep(5);
final var end = System.nanoTime();
// 5.012795 秒
System.out.printf("%f 秒%n", (end - start) / 1000000000.0);
多少の誤差はありますが、無事、5秒停止することができました。
Thread.sleep(5000);
TimeUnit.SECONDS.sleep(5);
Thread.sleep に比べて、多少タイピング量は増えています。
ただ、5秒止めるというのが明確になったのではないでしょうか。
まとめ
停止時間 | TimeUnit | Thread |
---|---|---|
300ミリ秒 |
|
|
5秒 |
|
|
1分 |
|
|
横に並べて比較してみるとどうでしょうか?
TimeUnit のほうが分かりやすく感じますでしょうか。
ほんのちょっとの違いかもしれません。
自分だけが読むコードであれば、そこまでソースコードの可読性は気にしなくてよいかもしれません。
しかし、多人数で開発していて自分以外もコードを読むのであれば、可読性は少しでもよくしたいですね。
関連記事
- API 使用例
- BlockingQueue (ブロッキング・キュー)
- Callable
- CancellationException
- ConcurrentHashMap.KeySetView (並列処理用セット)
- ConcurrentLinkedDeque (並列処理用・両端キュー)
- ConcurrentLinkedQueue (並列処理用キュー)
- ConcurrentMap (並列処理用マップ)
- ConcurrentModificationException (並列処理例外)
- ConcurrentSkipListSet (並列処理用セット)
- Condition (同期)
- CopyOnWriteArrayList (並列処理用リスト)
- CopyOnWriteArraySet (並列処理用セット)
- CountDownLatch (同期)
- CyclicBarrier (同期)
- Exchanger (同期)
- Executor
- ExecutorService
- Executors
- Future
- Future.State
- FutureTask
- InterruptedException (割込み例外)
- Lock (同期)
- Object (オブジェクト)
- Runnable
- Semaphore (セマフォ)
- Thread (スレッド)
- ThreadGroup
- ThreadLocal
- TimeUnit