シリーズ一覧
[Java Gold対策] はじめてのスレッド 1日目 : スレッドとは?
[Java Gold対策] はじめてのスレッド 2日目 : スレッドの作り方
[Java Gold対策] はじめてのスレッド 3日目 : スレッドの作り方2
[Java Gold対策] はじめてのスレッド <よりみち1> : 匿名クラスで書く。
[Java Gold対策] はじめてのスレッド <よりみち2> : ラムダ式で書く。
[Java Gold対策] はじめてのスレッド 4日目 : スレッドをsleepさせよう
[Java Gold対策] はじめてのスレッド 5日目 : joinメソッドで待たせる
[Java Gold対策] はじめてのスレッド 6日目 : runメソッドで条件付き停止
runメソッドを応用しよう
runメソッドを活用しよう
[ Java Gold 対策 ] はじめてのスレッド 5日目に引き続き、スレッドの処理を制御してくれるメソッドを紹介していきます。
とはいっても、今回は初めてのメソッドは出てきませんよ!
今回の主役は、最初からずっとお世話になっているrunメソッドさんです。
こんなときに使える
スレッドを使っていると、外部から何らかの条件が満たされたらそのスレッドを停止したい、ということがあります。 たとえば、ユーザーがキャンセルボタンを押したときなどです。
今回の内容は、ユーザーのアクションに応じて処理を調整することができるという内容です。
なので、これができるようになると、いよいよアプリケーションとしての要素が強くなってきますね!
イメージとしては、こんな流れです。
webサイトのボタンが押される
↓
その反応がメインのスレッドに帰ってくる
↓
反応をきっかけに、止めたいスレッドの条件を変更する
↓
サブのスレッドが停止する
「条件を変更する」の部分が、今回のミソです。
それでは早速見ていきましょう!
runメソッドを条件付きで停止させる
新しくスレッド生成する際には、runメソッドにさせたい処理を書いていました。
実は、新しいスレッドのrunメソッドの処理がすべて終われば、そのスレッドは消滅します!
つまり、スレッドの外部からスレッドを好きなタイミングで止めたいときには、runメソッドの処理を終了させることで、スレッドの処理を止めることができます。
シンプルですね
runメソッドにひと工夫
public void run() {
while ( 条件 ) {
繰り返し行う処理
}
}
このコードでは、条件式がfalseになった時点で、runメソッドが終了し、スレッドが止まります。
そして、外部からのアクションでこの条件式の値を変更できれば、外部からスレッドの進行を操作できることになります。
このひと工夫を仕込むだけなんです。
早速具体的なコードを見ていきましょう!
具体的に見てみる。
サンプルコード
このコードには、SampleThread6というクラスと、ThreadStopMainというクラスの2つがあります。
- SampleThread6:Threadクラスを継承して、runメソッドをオーバーライドしている
- ThreadStopMain:mainメソッドで新しいスレッドを生成して、処理を操作する
class SampleThread6 extends Thread {
// 外部から変更できるような修飾子にしておく
public boolean running = true;
public void run() {
// runningがtrueであれば、*を表示し続ける
while (running) {
System.out.print("*");
}
System.out.println("runメソッドを終了します。");
}
}
public class ThreadStopMain {
public static void main(String[] args) {
SampleThread6 t = new SampleThread6();
t.start();
try {
// 1ミリ秒停止する
Thread.sleep(1);
} catch (Exception e) {
System.out.println(e);
}
// tのメンバー変数runningをfalseに変更
t.running = false;
}
}
実行結果:1ミリ秒後に*の表示が停止し、メッセージが表示されます。
(1ミリ秒後までに処理できる作業量は環境やデバイスによって変わるので、*の数は変動します。)
**********************runメソッドを終了します。
1行ずつ解説
処理が少し複雑なので、行番号で解説していきますね。
- 最初・18行目:
mainメソッドでstartメソッドを呼び出すことで、マルチスレッドを開始します。 - 22行目:
runメソッドの処理は続きますが、mainメソッドはsleepメソッドによって1ミリ秒間停止します。 - 26行目:
mainメソッドのスレッドが1ミリ秒後にsleepを抜けると、runメソッド内の条件式であるrunnningをfalseに変更します。 - 4行目:
runningはmainメソッドからアクセスできるような修飾子にしておく。
つまり、条件式を、操作元のメインのスレッドからアクセスできるようにしておく。(→詳しく解説) - 結果・11行目:
runメソッドの処理は終了し、スレッドの処理は中止します。
このように、ある一つのスレッドを他のスレッドから中止する際は、ほかのスレッドから条件式を変更することで、ループを抜けだすような方法を使います。
条件式のアクセス修飾子について
mainメソッドのスレッドから、runメソッドの条件式を変更する必要があるので、
アクセス修飾子に気をつける必要があります。
4行目についてもう少し説明しますね。
// 4行目
public boolean running = true;
ここでは、「public」で修飾していますね。
今回のコードでは、mainメソッドとrunメソッドが同じパッケージにあるので、privateでなければ、どの修飾子でも実行可能です。
このように、「操作する側のスレッド」と「操作される側のスレッド」のパッケージの位置関係を意識して設定する必要があります。
まとめ
今回のコードは今までと比べてちょっと処理が行ったり来たりで大変でしたね
でもその分、少しずつですが高度なことが表現できるようになった、ということですね!
今回のサンプルコードでは、runメソッドの処理を、mainメソッドから操ることができるようになっていました。
つまり、一つのスレッドの処理を、別のスレッドから操ることができます。
これを実際にコードにするときは、当たり前に聞こえるかもしれませんが、
- runメソッドの処理を、あらかじめ条件で変更できるように、工夫しておく
→ whileループなどで処理をまとめる - その条件をメインのスレッドで変更できるようにしておく
→ アクセス修飾子をメインのスレッドからアクセスできるように
という工夫が大事です。覚えておきましょう!
シリーズまとめ
これにて、はじめてのスレッドシリーズは終わりになります。
皆さん、スレッドについて掴めたでしょうか?
試験対策を行う際は、この基本の使い方をしっかり抑えてから入ってみてくださいね♪
ここまで読んでいただきまして、ありがとうございました!
次の記事でお会いしましょう
コメント