- PR -

スレッドの停止の仕方について

投稿者投稿内容
taka
常連さん
会議室デビュー日: 2003/09/22
投稿数: 46
投稿日時: 2003-10-28 17:02
いつもお世話になっております。

スレッドの停止の仕方について、私のとっている方法が正しいのかわからなくなり質問させていただきます。

以下はスレッドを開始/停止する為の関数です(threadOnOff)。
引数に"True"が来たらスレッド開始。
   "False"が来たらスレッド停止、です。
void threadOnOff(boolean sw) {
  if(sw == true){
   threadScroll = new Thread(this);
   threadScroll.start();
  } else {
   if(threadScroll != null) {
    //スレッド停止
    threadScroll.interrupt();
    //スレッド終了待ち
    try{
     threadScroll.join();
    } catch(InterruptedException e){ e.printStackTrace(); }
    threadScroll = null;
   }
  }
}

そして以下がRUNです。
public void run(){
  try {
   threadScroll.sleep(clsItfc.threadSleep);
   while (threadScroll != null) {
    threadScroll.sleep(clsItfc.threadRun); //0.05秒間隔で動きます。
//ここにスレッド処理があります。
   } catch (InterruptedException ie) { System.out.println(ie.getMessage }
}

以前は停止の際にthreadScroll = nullをして止めていたのですが、
実際にスレッドが停止するまでに少しタイムラグがあった為、
強制的にthreadScroll.interrupt();のようにして停止させております。

しかし、このような停止の方法は良いのかと疑問に思ってしまいました。
皆様のご意見と、私ならこうするといったアドバイスをお聞かせください。
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-10-28 17:25
ども、ほむらです。
単にやり方を知らないだけなのですが
僕はスレッド用のクラス変数でフラグを使用しています。
とめたいときはこのフラグをFalseにしてnullを代入する形ですか?

フラグを使用する関係で
スレッドごとにクラスが出来ていたりします。。。

たとえば。
コード:

void run(){
while( bThreadAlive == true ){
// loop
}
}

void xxxx(){
tobj.bThreadAlive = false;
tobj = null;
}


といった感じです。
かなり省略していますけど^^;;;;;


[ メッセージ編集済み 編集者: ほむら 編集日時 2003-10-28 17:29 ]
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2003-10-28 17:34
チュートリアルです。
http://java.sun.com/docs/books/tutorial/essential/threads/lifecycle.html
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-10-28 18:55
このサイトの「スレッド停止時の終了処理はどうすれば実行できるか?」が参考になると思います。
taka
常連さん
会議室デビュー日: 2003/09/22
投稿数: 46
投稿日時: 2003-10-28 19:05
ほむらさん、ぽんさん、ご意見ありがとうございました。

説明が不足していた個所を書かせていただきます。
記載した"threadOnOff"の関数なんですが、連続して行われる事があります。
例) theadOnOff(true)→threadOnOff(false)→threadOnOff(true)

ほむらさんのご意見の場合
例えば連続すると、"threadOnOff(false)"内でフラグをfalseにしたのに"Run"の"while"文
の判定が行われる前に次の"threadOnOff(true)"が行われ、そこでフラグがまたtrueに戻されるといった現象がありました。
本当は下記のように流れてくれるとスレッドは止まるのですが・・・
1.threadOnOff(false)

2.run内部のwhile文チェック(フラグがFalseの為、スレッドは止まる)

3.threadOnOff(true)

私の場合下記のようになり結局、処理速度?により下記のような流れになってしまった事がありました。
1.threadOnOff(false)

2.threadOnOff(true)

3.run内部のwhile文チェック(フラグがTrueの為、スレッドは止まらない)

ぽむさん、教えていただいたURLを読んでみようと思います。ありがとうございました。


Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2003-10-29 00:19
threadへの interruptは、割込んだことを記憶させることができますが、
現在の処理を直ちに終了させるかどうかは、処理系に依存します。
特に、Socketの accept, io の read, writeでのブロック中に
interruptで抜け出すものと、そうでないものがあります。

Solaris, Linux, Win の各バージョンの JREで調査したことありますが、
それを説明することはあまり意味がありません。どうかそのような違いに
依存しない設計をして下さい。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-10-29 00:26
unibon です。こんにちわ。

引用:

takaさんの書き込み (2003-10-28 17:02) より:
以前は停止の際にthreadScroll = nullをして止めていたのですが、
実際にスレッドが停止するまでに少しタイムラグがあった為、
強制的にthreadScroll.interrupt();のようにして停止させております。


#直接の回答ではないですが。
このやりかた(threadScroll = null)でスレッドを止めることができるとは、
意外でした。私は今まで見たことがありませんでした。

ただ、おそらくガーベッジコレクションに強く依存すると思いますので、
ガーベッジコレクションが動くまでの間は、おっしゃるようにタイムラグがあるはずです。
また、ガーベッジコレクションが必ず動くとは限らないので、
スレッドも必ず止まるわけではないでしょう。
Keisuke
大ベテラン
会議室デビュー日: 2003/10/24
投稿数: 105
投稿日時: 2003-10-29 04:10
 while (threadScroll != null) {
にしても、
while( bThreadAlive == true ){
にしても、マルチスレッド環境では問題がありそうです。
起動時の判定に問題があると、複数のスレッドが走り続ける。

素直に、下記のようにするのがよいのでは。
http://java.sun.com/products/jdk/1.2/ja/docs/ja/guide/misc/threadPrimitiveDeprecation.html

スキルアップ/キャリアアップ(JOB@IT)