ほぼ1年間、私はJavaコーディングに集中的に取り組んできました。 マルチスレッドに関する私の意見ではかなり深刻な問題に直面しており、OracleのJVMの現在の実装のフレームワークでは解決できないように思えます(上記はJDK 1.5以降に適用されます)。 実際のところ、Javaの現時点では、スレッドの実行を確実に停止する方法はありません。 この投稿では、なぜそうなのかを説明し、この問題を解決する方法について議論を始めることを提案します。
些細な作業のように思えます。特定の
スレッド (スレッド)がありますが、これは確かに、いくつかのリソースを消費しながら絶望的にハングします(ループする可能性があります)。 それで何をしますか? リソースを解放したいと思います。 それは簡単だと思われますか? しかし、問題の詳細な調査の結果、JVMには、スタックしたスレッドを正しく停止するための命令がないことがわかりました。 古い
Thread.stop()メソッドはDeprecatedおよび
anathematizedと宣言されています。 javadocで述べられているように、このメソッドは「本質的に安全ではありません」。 まあ、私たちが安全でない場合、私たちはそれを使用せず、別の安全な方法を与えます。 しかし、別の安全な、奇妙なことに、提供されていません。 非常に安全な
Thread.interrupt()命令が確実に提供されます。 しかし、残念ながら、彼女は絶対に何もしませんので、彼女は安全です! これはストリームへの単なるメッセージです:「やめてください」。 ただし、スレッドがこのメッセージを無視した場合は、ドキュメントの「スレッドがThread.interrupt()に応答しない場合、アプリケーション固有のトリックを使用できます」に記載されているとおりです。 許可していただきありがとうございます。 いわゆる、必要に応じてスピンします。
タスクがスレッドプールで、たとえば
ExecutorService.submit(Runnable)を介して起動されると、すべてがさらに複雑になります。 同時に、指定されたタスクがどの特定のスレッドで実行されるかさえわからず、禁止されているThread.stop()を使用することさえできなくなります。 一方、
Futureにはリンクがあり、Futureには
Future.cancel(boolean)メソッドがあり、タスクをキャンセルする必要があります。 ただし、タスクが既に開始されている場合、Future.cancel(true)を呼び出しても実際には停止しません。
FutureTask実装の腸内で、コードが実行されます。
if (mayInterruptIfRunning) {
Thread r = runner;
if (r != null)
r.interrupt(); }
つまり 繰り返しますが、タスクを実行しているスレッドは、実行を停止するためにのみ推奨されます。 さらに、タスクが現在実行されているかどうかを確認する機会すらありません。
Future.isDone()メソッドがありますが、タスクの実行が完了したときだけでなく、Future.cancel()を呼び出した直後に、タスクがまだ実行中であってもtrueを返します(Future.cancel(true)は既に実行を開始しているタスクを停止します)。
まあ、自分ですべてのコードを書いたら、適切な場所で
Thread.isInterrupted()を慎重に処理することができ、すべては問題ありません。 しかし、サードパーティのコードを実行する場合はどうでしょうか? プラグインで拡張可能なサーバーが必要ですか? フリーズされたプラグインの実行を正しく中断できないため、一部の不正に作成されたプラグインは、サーバー全体の動作不能状態に容易につながる可能性があります。
申し分なく、満足のいく解決策がわかりません。 Thread.stop()メソッドはそれほど危険ではないでしょうか? これについて、Javaプログラマーの実践者の意見を聞きたいです。