- ベストアンサー
Threadの停止について
Java初心者です。 一応過去ログも見てみたのですが、解らなかったので質問いたします。 Threadの動作を完全に停止する場合、stop()メソッドは推奨されない 命令として扱われていますが、stop()を使わずに完全に停止する方法は ありますでしょうか。 よろしくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#1です。 #2さんのお礼で誤解があるようですので補足しておきます。 下のスレッドは、0xffで埋められた約5MBのファイルを作るものです。 「キャンセルされた場合ファイルを消す」という仕様です。 (例外処理は省略しました) 5000000回のループが終わるとスレッドが終了しますが、 外部からdoCancel()メソッドを呼び出されても終了します。 スレッドのループ内で、キャンセルされているかチェックし、 キャンセルされていれば後始末(ファイルの削除)をして終了します。 なお、doCancel()、isCanceled()がsynchronizedなのは、 変数canceledに排他をかけるため。 変数canceledにvolatileが付いているのは、コンパイラの最適化による誤動作を 防ぐためです。 それと、stop()は非推奨のため、やはり使わないほうがいいでしょう。 class MyThread implements Runnable { volatile boolean canceled = false; /**スレッドの実行を終了させる */ synchronized public void doCancel(){ canceled = true; } /**スレッドがキャンセルされたか調査する */ synchronized public boolean isCanceled(){ return canceled; } public void run(){ File file = new File("........"); FileOutputStream fos = new FileOutputStream(file); for(int i = 0 ; i < 5000000 ; i++){ if(isCanceled()){ fos.close(); file.delete(); return; } fos.write(0xff); } fos.close(); } }
その他の回答 (2)
要するに、別スレッドで実行するrunメソッドを終了すれば、そのスレッドは終わります。状況に応じてrunを(中断ではなく)終了すればいいのです。 通常、常にスレッドで処理をし続けるというような場合は、runの中で無限ループのように処理を繰り返し続けるようになっていますね。そこで、必要に応じて繰り返しを抜けるようにすればいいわけです。 boolean runflag = true; public void run(){ while(runflag){ ・・・実行する処理・・・ } } 例えばこんな具合にしておき、スレッドを終了したいときは、runflag = false;にすれば、whileを抜けてrunを終了します。終了すればスレッドはおしまいです。
お礼
Kyon2_PaPaさん、回答ありがとうございます。 頂いた方法は検討してはいたんですが、 要はいくつものスレッドが増えていくと処理的に重くなって しまうのではないかと思い、完全に停止したほうが良いと 思っていました。 もし、この方法で問題なければ、試してみようと思います。
- ngsvx
- ベストアンサー率49% (157/315)
外部から停止させられる可能性のあるスレッドは、 停止用のメソッドを用意して、自分で停止処理をします。 機械的に勝手に停止させられると、データに不整合が起こる場合があるからです。 どのような不整合が起こるのかは、プログラム個別に違いますから、機械的に停止するstopメソッドは非推奨になっています。
お礼
ngsvxさん、ありがとうございます。 つまり、stop()を使わずにプログラムの流れ的に 実行しないようにするということでしょうか。 自分で不整合の可能性が把握できていれば、stopは使っても 大丈夫なのでしょうか。 よろしくお願いいたします。
お礼
ngsvxさん、またまたありがとうございました。 少し想定していた内容と異なっていましたが、 なんとなく流れはつかめました。 早速試してみようと思います。 ありがとうございました^^