もう1つのタイマー
実をいえば、Javaにはもう一つのタイマーがあります。こちらはSwingに用意されているもので、SwingベースのGUIをタイマーで操作するために利用します。GUIなどで利用されるActionListenerをタイマーの実行対象として指定できる点が特徴です。
import javax.swing.Timer; /* 以下のimportは省略 */ class TimeLabel extends JLabel { private DateFormat format; public TimeLabel(){ this.setFont(new Font("Dialog",Font.BOLD,24)); format = new SimpleDateFormat("HH:mm:ss"); ActionListener action = new TimerLabelActionAdapter(); Timer timer = new Timer(1000,action); timer.start(); } public void setTime(){ Calendar calendar = Calendar.getInstance(Locale.JAPAN); this.setText(format.format(calendar.getTime())); } class TimerLabelActionAdapter implements ActionListener { public void actionPerformed(ActionEvent e) { setTime(); } } }
先のサンプルで、TimeLabelをこのように修正してみましょう。また、インポートの宣言を次のように変更してください。この修正によって、コード内の「Timer」はjavax.swing.Timerを意味するようになります。
/* 修正前 */ import java.util.Timer; /* 修正後 */ import javax.swing.Timer;
ActionListenerをスケジューリングする
先ほど説明したjava.util.TimerがTimerTaskを実行するためのクラスであったのと違って、このjavax.swing.Timerは指定のアクションを実行するためのクラスとなっています。TimeLabelのコンストラクタを見てみましょう。
ActionListener action = new TimerLabelActionAdapter(); Timer timer = new Timer(1000,action); timer.start();
まず、ActionListenerであるTimerLabelActionAdapterのインスタンスを生成します。次に、このインスタンスと実行間隔の値(ミリ秒)を引数に指定して、Timerのインスタンスを生成します。最後にstartメソッドを呼び出してタイマーをスタートさせます。これで指定された時間が経過するごとに、引数で指定したActionListenerのactionPerformedメソッドが実行されるようになります。
ActionListenerの作成は、既にSwingを使っていればお手のものでしょう。GUIのイベント処理感覚でタイマー処理が実現できる点は実に便利です。サンプルコードでは専用のActionListenerを用意しましたが、もちろんJButtonなどに設定されいるActionListnerなどをそのまま利用することも可能です。どこかのボタンなどに割り付けてある処理を定期的に実行したいような場合は、こちらの方法が圧倒的に簡単でしょう。
スレッドによる並列処理
プログラムで行いたい処理は必ずしも「ひとつの処理を継続して実行する」ことだけではありません。時には「こっちの処理をやりながら、こっちの処理も進める」ようなことも必要になってきます。同時並行的にいくつかの処理を進めたいという要望に応えるために、多くのプログラムでは「スレッド」と呼ばれる概念を導入しています。
スレッドは、処理を実行するひとつの単位です。Java仮想マシンは、プログラムの実行に際して「メインスレッド」と呼ばれるスレッドを用意し、その中でmainメソッドを実行します。特に必要がない限り、このメインスレッド内(場合によっては、メインスレッドから派生したスレッド内)でプログラムは実行されていく、と考えてよいでしょう。
これまで説明した2種類のTimerクラスによる処理は、他の操作とは別に実行されていましたが、実はこれもスレッドによるものです。Timerクラス実行時には専用の「バックグラウンドスレッド」という特別なスレッドが用意されます。このスレッドにタスクのスケジューリングが行われ、定期的に実行される仕組みになっているのです。
メインスレッドとは別の独立したスレッドを用意すれば、メインスレッドと新スレッドの両方で同時に平行して処理を実行できる、というわけです。Javaの場合、Threadというクラスを利用すると、処理を新しいスレッドとして実行することができます。
