ふと、Java Timerクラスというのがあったことを思い出して、確認。
使い方は次のような感じ。Threadを直接使うよりわかりやすいといえばわかりやすい。scheduleAtFixedRate()の他にschedule()もあるが、同じ間隔で実行したい場合は前者を使う。ある処理をしてから一定時間待機してから処理をしたい場合は後者を使う。
package org.sssg.soft.sample.timer; import java.util.Timer; import java.util.TimerTask; public class SimpleCountDown { private final static int INTERVAL = 1000; private final static int COUNT = 10; public void run() { final Timer timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { int i = COUNT; public void run() { System.out.println(i--); if (i < 0) { timer.cancel(); } } }, 0, INTERVAL); } public static void main(final String args[]) { SimpleCountDown app = new SimpleCountDown(); app.run(); } }
プログラムの終了時点で、Timerクラスのcancel()メソッドを呼び出して明示的に終了させる必要がある。ちなみにcancel()メソッドは実行の予約をキャンセルして破棄するだけで、実行中なら処理は継続されて、処理終了後に破棄される。リソース解放のために必ず指定が必要なのが注意点。キャンセルがたくさん発生する場合はpurge()メソッドも併用するとよい。
Timer(boolean isDaemon) コンストラクタを使うと、ユーザスレッドでTimerを起動するか、デーモンスレッドでTimerを起動するか指定できる。終了処理が確実に必要ならユーザスレッドで起動し、タスクがキューに残っていても終了処理が必要なくて破棄してよいのならデーモンスレッドで起動する。手軽に使ってメモリリークをしたくないならデーモンスレッドでよいだろう。
スレッドはTimerオブジェクト単位で用意されるので、複数のTimerTaskを同一Timerへ登録するとリソースの節約になる。