- - PR -
スレッドの停止の仕方について
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-10-29 15:09
ほむらさんのサンプルに対するコメント。
いきなり、ThreadOnOff(false)が呼ばれた場合のために、
とした方が良いように思えます。 # それとも、nullでmonitor握るのは、OKなのかな? | ||||||||
|
投稿日時: 2003-10-29 15:17
Keisuke です。
最初のコードから以下のようなものを想定してみました。
このコードでは stopWorkr の tobj.bThreadAlive = false の後で スレッドスイッチが起こり、startWorker が呼ばれた場合に参照されない スレッドが生き残ってしまいます。 実際には同期ブロックを使ってられるので、このような事は起きませんね。 ただ ThreadOnOff(true) の if( t != null ) ThreadOnOff( false ); の後に、別スレッドから又 ThreadOnOff(true) が呼ばれると同じような スレッドが出来てしまいます。 スレッド競合によるバグは見つけ辛いので、危険の芽は早めに・・・ | ||||||||
|
投稿日時: 2003-10-29 17:27
ども、ほむらです。
------- taka氏へ
そういうパターンもあるんですね(笑 t.start(); のあとに Thread.sleep(10); としても同じですかね。。。 あと、各スレットごとにインスタンスが異なるので bThreadAlive=false;のあとtrueにすることは出来ません。(このつくり方ならばの話) コンストラクタ以外でtrueにならないし kill()以外でfalseにもならないことは 保証されています。 この作り方のミソはフラグがスレッドを実行するクラスのクラス変数であるということです。 なのでインスタンス単位で値の保証もされていると認識しています。 かずくん氏へ ご指摘どおりですね^^;; >if (null != t) { で判定は必要です。。 修正個所は二つかな? 以下は修正後のThreadOnOff()です。
# Keisuke氏のいうパターンも当てはまる気がするので # 誤字の修正と太字部分(synchronized)の追加。。 # もしかして僕宛の指摘だったのでしょうか? [ メッセージ編集済み 編集者: ほむら 編集日時 2003-10-29 17:38 ] | ||||||||
|
投稿日時: 2003-10-29 17:45
ほむらです。
------ 良く考えたらsleep()を使用すると環境依存っぽくなってしまうので もう一つフラグを作ってrun()内部でwhile()の前にtrueに変更して sleep()のかわりにこのフラグがtrueになるまで待つといった 形にしたほうが良いかもしれません。。。。 | ||||||||
|
投稿日時: 2003-10-29 18:33
こんにちはWataです。スレッドが既にだいぶ進んでしまっていますが、以下について。
試してみたところ、Threadがinterruptされてから、その後にsleepやwaitを 行うと、即時にInterruptedExceptionが発生するようでした。 したがってwhileでチェックしなくても、次のsleepまで停止が遅れるだけのようです。 ただし私の環境では、sleepの引数が0だとInterruptedExceptionが発生しませんでした。 | ||||||||
|
投稿日時: 2003-10-29 18:59
Wataさん、ご意見ありがとうございました。
>試してみたところ、Threadがinterruptされてから、その後にsleepやwaitを >行うと、即時にInterruptedExceptionが発生するようでした。 私も確認できました。しかし、Wataさんがおっしゃったように "Thread.isInterrupted()"をWhile文の中に付け加えるべきだと考えました。 見た目もロジックから意図が読めますしね。 ありがとうございました。 | ||||||||
|
投稿日時: 2003-10-30 08:31
ほむらさんのthreadOnOff()メソッドについて
threadOnOff(true)で処理される場合、"synchronized(t){"で "NullPointerException"になりません? | ||||||||
|
投稿日時: 2003-10-30 09:54
ども、ほむらです。
taka氏へ
太字の部分ですよね。 ごめんなさい、実験してませんでした^^;;; やってみたらご指摘のとおり例外が発生しました。 ところで、きのうふとおもったのですが synchronized public void ThreadOnOff(boolean sw) としてしまえば内部のsynchronize(t)の部分は不要になるのかなーと 思ってみました。。。 関数の性質上同期は必要ですしね。 | ||||||||
