スレッドの開始と終了
さて、ここからはスレッドの開始と終了について説明します。必要に応じてスレッドを開始したり終了したりするにはどうすればよいのでしょうか。実を言えば、ThreadやRunnableには、スレッドの停止や再開のための機能はありません。実は、以前には存在していたのですが、スレッドのデッドロックを招く恐れがあり、すべて非推奨となりました。
では、どうすればいいのか。
実は簡単です。スレッドを終了したい場合は、実行中のrunメソッドを抜けて通常通りにメソッドを終了させます。再開したい場合は、再度Threadインスタンスを作成し、処理を開始をします。
package codezine.java; import java.awt.*; import java.awt.event.*; import java.text.*; import java.util.*; import javax.swing.*; public class Sample extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; private TimeLabel label; private JCheckBox check; public static void main(String args[]) { Sample sample1 = new Sample(); sample1.setBounds(100,100,300,100); sample1.setVisible(true); } public Sample() { label = new TimeLabel(); this.add(label,BorderLayout.CENTER); check = new JCheckBox("clock"); check.addActionListener(this); this.add(check,BorderLayout.NORTH); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent e) { label.setThread(check.isSelected()); } } class TimeLabel extends JLabel implements Runnable { private static final long serialVersionUID = 1L; private DateFormat format; private boolean roop_flag; public TimeLabel(){ this.setFont(new Font("Dialog",Font.BOLD,24)); format = new SimpleDateFormat("HH:mm:ss"); } public void setThread(boolean f){ if (f){ roop_flag = true; Thread thread = new Thread(this); thread.start(); } else { roop_flag = false; } } public synchronized void setTime(){ Calendar calendar = Calendar.getInstance(Locale.JAPAN); this.setText(format.format(calendar.getTime())); } public void run() { while(roop_flag){ try { Thread.sleep(1000); } catch(InterruptedException e){ e.printStackTrace(); } setTime(); } } }

サンプルにチェックボックスをつけ、ONにすると時計が動き、OFFにすると止まるようにしてみました。スレッドの開始・終了は、setThreadというメソッドで行っています。引数で渡されたbooleanの値をもとに、trueならば新規にThreadを作成してstartし、falseならばroop_flagにfalseを設定します。開始・終了に必要な操作は、実にたったこれだけです。
もちろん、これだと毎回スレッドを新規に開始することになります。例えば継続的な処理などの場合には、中断する度にすべて初期状態に戻るようでは困ることもあるでしょう。そのような場合は、現在のオブジェクトをフィールド等に保管しておき、新規にスレッドを作成したらそれをもとに現状復帰する、といった処理を考える必要があるでしょう。
しかし、とりあえずは終了はループを抜ける。再開は新規にスレッドをスタートするという基本的な考えをしっかり理解しておけば、その利用はそう難しいものではないはずです。
まとめ
今回は、タイマーとスレッドの基本的な使い方について説明しました。タイマーは何となく想像できるものでしょうが、スレッドは慣れないとイメージがつかみにくい概念かもしれません。
まずは、実際にスレッドを使ってみて、「同時に複数の処理が並行して動く」ということがどういうことか体験してみてください。そして、スレッドの働きを実際に確認をしておきましょう。
タイマーは、スレッドよりも使い方がやや限定されますが、実行スレッドの管理などを考えずに済みます。スレッドは、自由に複数の処理を扱えますが、あまり考えずに多用すると全体のパフォーマンスを下げることにもつながります。まずは、「その処理はタイマーで実現可能なものかどうか」を考えるのが良いでしょう。あえて管理の難しいものをわざわざ使う必要はないのですから。
