- 締切済み
javaでアプレットを使用していますが、
javaでアプレットを使用しています。 startメソッドでkicker.start();しているのに、 stopメソッドではkicker=null;はしているものの、 kicker.stop();は推奨されていません。 これで開始されたスレッドが停止するのでしょうか?
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- hitomura
- ベストアンサー率48% (325/664)
> blinker == thisThread > > がよくわかりません あー……すみません。自分の先の回答、あなたの質問文に出てこないコードがいきなり出てちょっと混乱するかもしれませんね。 blinker == thisThread というコードは自分が提示した「Java 推奨されないスレッドプリミティブ」というページの「Thread.stop の代わりに何を使うべきですか」という見出しのところにあるコードが元です。自分の回答の後半は、なぜこのコードでスレッドが止まるのかということについての説明です。 > public void run() { > Thread.currentThread().setPriority(Thread.NORM_PRIORITY-3); > while(kicker != null) { > repaint(); > try { > Thread.sleep(100); > } catch(InterruptedException e) {} > } > kicker=null; > } > > この止め方はどうですか? はっきり言ってkicker=nullを入れた位置が無意味です。 なぜなら、whileループが終わったときkickerはすでにnullになっており、そこにnullを再度代入しているからです。 逆に、何らかの手段でwhileループの継続条件であるkicker != nullを偽にしないと、whileループは延々と回り続けることになり、run()メソッドが終了しないためこのスレッドは止まりません。
- hitomura
- ベストアンサー率48% (325/664)
kicker のクラスがなんなのかわかりませんが、スレッドと言っていてstop()メソッドが非推奨ということからThreadクラスを派生したものでしょうか? とりあえず上記の通りであると仮定して回答……しようとしたら公式のほうにstop()が非推奨な理由とその代わりにどう変更すべきかが書かれています。 http://docs.oracle.com/javase/jp/6/technotes/guides/concurrency/threadPrimitiveDeprecation.html (表示が乱れる場合は表示エンコードをUnicode UTF-8にしてください) ひょっとしたらすでにこちらを参照されてkicker=null;とされている上でのご質問かもしれませんね。 その場合の答は、ええ、上記の代入「だけ」ではスレッドは止まりません。 上記ページの変更前と変更後をよく見てください。stop()以外にrun()にも修正が入っています。 この変更、whileの持続条件がtrueからblinker == thisThreadに代わっていることと上記の代入とが合わさることでrun()の処理(つまりスレッド処理)を止めることができます。 このサンプルコードでスレッドが動き続けるのはwhileの持続条件が成り立ち続けているためです。 変更後ではここでwhileに入る前のblinkerであるthisThreadと現在のblinkerとを比較しています。 どこかからstop()が呼ばれるまでblinkerの値はthisThreadと一致するため、この比較は一致しwhile内の処理が実行されます。 一方、いったんstop()が呼ばれるとblinkerの値はnullになりthisThreadと一致しません。したがって、whileの次の処理を行いますが、この場合は直後でメソッドが終了しているためrun()メソッドが終わります。 まとめると、スレッドを止めるには ・何らかの終了指示フラグをスレッド実行側に持たせる ・スレッド実行側ではスレッド実行中に適切な間隔で終了指示フラグを確認する ・外部から止めるには終了指示フラグをオンにする事だけを行う。外部からスレッドを無理やり止めてはいけない。 ということを実装する必要があります。サンプルコードの例では終了指示フラグとしてblinker自体を使っているだけです。Threadクラスのインスタンスの参照を外すとそのスレッドの処理が終了することは決してありません。
補足
すいません。もう1つ突っ込んでおねがいします。 blinker == thisThread がよくわかりません。 run()は次のようになっています。 public void run() { Thread.currentThread().setPriority(Thread.NORM_PRIORITY-3); while(kicker != null) { repaint(); try { Thread.sleep(100); } catch(InterruptedException e) {} } kicker=null; } この止め方はどうですか?
補足
再度すいません。 では、最初からこうすればよかったですね。 public void run() { Thread.currentThread().setPriority(Thread.NORM_PRIORITY-3); while(kicker != null) { repaint(); try { Thread.sleep(20); } catch(InterruptedException e) {} } kicker=null; //コレは不要 } public void update(Graphics g){ paint(g); } public void start() { if(kicker == null) { kicker = new Thread(this); kicker.start(); } } public void stop() { if(kicker != null) { //削除 kicker.stop(); kicker = null; } } で良いということですね。