私はWindows7OSを使用しています。私のアプリケーションには6
スレッドがあります。アラートをテストしてスレッドの状態を確認するために、スレッドを手動で強制終了し、アラートが正しく機能しているかどうかを確認する必要があります。プロセスを強制終了するのと同じように、スレッドを強制終了できますpid
か?
8 に答える
Dan Woodsは、このブログエントリでスレッドを強制終了する方法を文書化しました... https://web.archive.org/web/20160302023213/http://www.rhcedan.com/2010/06/22/killing-a-java -thread 彼が実行した手順には、デバッガー(JDB)を使用し、スレッドの実行に例外を挿入することが含まれていました。具体的には...
Javaプログラムが以下のパラメーターで開始されていることを確認してください。
-Dcom.sun.management.jmxremote.port = 50199
-Dcom.sun.management.jmxremote.authenticate = false
-Dcom.sun.management.jmxremote.ssl = false
-Xrunjdwp:transport = dt_socket、address = 50100、server = y 、suspend = nこれにより、問題の原因となっているスレッドを特定した後、実行中のプロセスにJavaデバッガーをアタッチできるようになります。また、管理しているホスト/ワークステーションからの50100および50199での接続のみを許可するように、iptablesが適切に設定されていることを確認してください。
- 問題のあるスレッドを特定します。
スレッドを殺します。この例では、ThreadNameは「btpool0-0?」です。Javaデバッガー(JDKディストリビューションにも付属)を起動し、実行中のJVMに接続します…</ p>
[root @ host〜]#jdb -attach 50100
実行中のスレッドのリストを取得します—これにより、JVMが認識しているスレッドIDも取得されます。
> threads
--snip--
(org.mortbay.thread.BoundedThreadPool$PoolThread)0x25cb
btpool0-0 running
--snip--
強制終了するスレッドIDは「0x25cb」です。スレッドを強制終了する最初のステップは、スレッドにジャンプして中断することです…</ p>
thread 0x25cb
btpool0-0[1] suspend 0x25cb
btpool0-0[1] step
Step completed: <... snip ...>
btpool0-0[1] kill 0x25cb new java.lang.Exception()
killing thread: btpool0-0
btpool0-0[1] instance of
com.site.package.name(name='btpool0-0', id=9675) killed btpool0-0[1]
Javaデバッガーを終了すると、完了です。
スレッドが存在するプロセスを強制終了せずにスレッドを「強制終了」する安全な方法はありません。意図的に実行するようなことではありません。テストの目的で、これをサポートするコードをアプリケーションに追加します。
それは真実ではない。スレッドIDがわかっている場合は、いつでもGDBを使用してJVMプロセスに接続し、pthread_killを呼び出すことができます。16進ID(ネイティブID)を提供するJavaスレッドダンプ(kill -3を実行)から変換するだけで、GDB(情報スレッド)のスレッドのリストを調べて、実際のスレッドIDを見つけることができます。
これは機能することが証明されています。
ピーターが言うように、これを安全に行うことはできません。実際、一部のプラットフォームThread.kill
では実装されていません。でも:
これがテストのためだけの場合、呼び出された単体テストは
Thread.kill
合理的です...それが機能する必要があるテストプラットフォームで機能したと仮定します。(ソースコードの「大声で」コメントは、ユニットテストを移植する人々を助けるためです...)もう1つの方法は、実行可能なスレッドにコードを追加して、単体テストでスレッドを終了するように指示できるようにすることです。これが機能するためにスレッドコードが(ほぼ)本番コードである必要がある場合は、テストの目的に合った方法で「壊れ」るように、何かをオーバーライドするサブクラスを作成できます。実際、このアプローチでは、制御された方法でスレッドを「中断」させることができ、アラートコードのさまざまな側面をテストできる可能性があります。
外部(OSまたはデバッガー)からそれを行うことはできません。ユーザーと対話して必要なスレッドを強制終了できる独自のスレッドウォッチドッグを作成する必要があります。
Javaでシグナルを処理する方法についてはこちらをご覧ください
Javaでは、UNIXのようなものを強制終了することはできません。Javaでトレッドするかinterrupt
、UNIXでプロセスを強制終了することができます。
スレッドでしばらく待って、コードでスレッドを強制終了します-簡単な方法です。
buzz3791による以前の投稿で述べたように、jdbを使用して機能します。ただし、私が気付いた変更は、スレッドを強制終了することはできませんが、スレッドを中断または一時停止することはできます。
#jdb -attach 50100
スレッド-これにより、jvmで実行されているすべてのスレッドが[グループと参照ハンドラー]セクションに表示されます。
グループ | 参照ハンドラー |
---|---|
:(com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary)0x36c1: | OrientDB(/xxx.xxx.xxx.xxx:123)<-BinaryClient(/xxx.xxx.xxx.xxx:678) |
thread 0x36c1--これは、強制終了/割り込みを実行してこの割り込みを実行するスレッド内のスレッドの1つから選択できるスレッドIDになります0x36c1
OrientDB(/xxx.xxx.xxx.xxx:123)<-BinaryClient(/xxx.xxx.xxx.xxx:678)[1]割り込み0x36c1
同じ割り込みコマンドを複数回試すことができます。すでに割り込みがかかっている場合は、スレッドIDが無効であることが示されます。したがって、スレッドが強制終了されていることがわかります。これは、スタックトレースを調べて確認することで確認できます。
jdk 8を使用してOrientDBデータベースサーバーでこれをテストし、動作します。