SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

作って覚えるJavaプログラミングのススメ

Java入門 (9) - タイマーとスレッド

作って覚えるJavaプログラミングのススメ 第9回

スレッドの開始と終了

 さて、ここからはスレッドの開始と終了について説明します。必要に応じてスレッドを開始したり終了したりするにはどうすればよいのでしょうか。実を言えば、ThreadRunnableには、スレッドの停止や再開のための機能はありません。実は、以前には存在していたのですが、スレッドのデッドロックを招く恐れがあり、すべて非推奨となりました。

※デッドロック
 複数のスレッドが互いに処理待ち状態となり全体が停止してしまうこと

 では、どうすればいいのか。

 実は簡単です。スレッドを終了したい場合は、実行中の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にすると停止する。
チェックボックスをONにすると時計が動き出し、OFFにすると停止する。

 サンプルにチェックボックスをつけ、ONにすると時計が動き、OFFにすると止まるようにしてみました。スレッドの開始・終了は、setThreadというメソッドで行っています。引数で渡されたbooleanの値をもとに、trueならば新規にThreadを作成してstartし、falseならばroop_flagfalseを設定します。開始・終了に必要な操作は、実にたったこれだけです。

 もちろん、これだと毎回スレッドを新規に開始することになります。例えば継続的な処理などの場合には、中断する度にすべて初期状態に戻るようでは困ることもあるでしょう。そのような場合は、現在のオブジェクトをフィールド等に保管しておき、新規にスレッドを作成したらそれをもとに現状復帰する、といった処理を考える必要があるでしょう。

 しかし、とりあえずは終了はループを抜ける。再開は新規にスレッドをスタートするという基本的な考えをしっかり理解しておけば、その利用はそう難しいものではないはずです。

まとめ

 今回は、タイマーとスレッドの基本的な使い方について説明しました。タイマーは何となく想像できるものでしょうが、スレッドは慣れないとイメージがつかみにくい概念かもしれません。

 まずは、実際にスレッドを使ってみて、「同時に複数の処理が並行して動く」ということがどういうことか体験してみてください。そして、スレッドの働きを実際に確認をしておきましょう。

 タイマーは、スレッドよりも使い方がやや限定されますが、実行スレッドの管理などを考えずに済みます。スレッドは、自由に複数の処理を扱えますが、あまり考えずに多用すると全体のパフォーマンスを下げることにもつながります。まずは、「その処理はタイマーで実現可能なものかどうか」を考えるのが良いでしょう。あえて管理の難しいものをわざわざ使う必要はないのですから。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
作って覚えるJavaプログラミングのススメ連載記事一覧

もっと読む

この記事の著者

掌田 津耶乃(ショウダ ツヤノ)

三文ライター&三流プログラマ。主にビギナーに向けたプログラミング関連の執筆を中心に活動している。※現在、入門ドキュメントサイト「libro」、カード型学習サイト「CARD.tuyano.com」を公開...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2597 2008/06/24 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー