22

Java でスレッドを作成した人を調べるにはどうすればよいですか?

以下を想像してみてください:複雑なプラグイン環境で~30 のサードパーティJAR を使用しています。それを起動し、多くのコードを実行し、いくつかの計算を行い、最後に shutdown() を呼び出します。

このライフサイクルは、実行のたびにいくつかの (非デーモン) スレッドがぶら下がったままになることを除けば、通常は正常に機能します。すべてのシャットダウンが最後のシャットダウンである場合、これは問題ありません。その場合は、 System.exit() を実行するだけで済みます。ただし、このサイクルは数回実行される可能性があり、パスごとにより多くのガベージが生成されます。

それで、私は何をすべきですか?Eclipse のデバッグ ビューにスレッドが表示されます。それらのスタック トレースが表示されますが、それらの起源に関するヒントは含まれていません。作成者のスタック トレースも、識別可能なクラス名も、何もありません。

この問題に対処する方法を知っている人はいますか?

4

5 に答える 5

14

さて、私は自分で問題を (ある程度) 解決することができました:

Thread.start() 

各呼び出しを手動で実行しました。このようにして、 Class.forName()が多くの静的コードを初期化し、その結果、これらの不思議なスレッドが作成されたことがすぐにわかりました。

私は自分の問題を解決することができましたが、より一般的なタスクはまだ解決されていないと思います.

于 2009-08-04T13:34:11.387 に答える
10

私は自分のスレッドに宗教的に名前を付けています (たとえば、 Thread(Runnable, String)を使用) 。スレッドをダンプすると、実行中のものと (したがって) 何がそれらを作成したのかが強調表示されます。これはサードパーティのスレッド作成を解決しません。感謝します。

編集: JavaSpecialist ニュースレターは最近 (2015 年 2 月)、セキュリティ マネージャーを使用してこの問題に対処しました。詳しくはこちら

詳細: JavaSpecialist 手法を使用するための詳細: SecurityManager API には、スレッド作成者のスレッドで呼び出される「checkAccess(newThreadBeingCreated)」が含まれています。新しいスレッドの「名前」はすでに初期化されています。したがって、そのメソッドでは、スレッド作成者のスレッドと新しいスレッドの両方にアクセスでき、ログ/印刷などを行うことができます。これを試してみると、監視されているコードがアクセス保護例外をスローし始めました。run() メソッドが監視対象のコードを呼び出した AccessController.doPriviledged(new PrivilegedAction() { ... } の下で呼び出すことで修正しました。

于 2009-08-04T12:42:53.010 に答える
1

Eclipseアプリケーションをデバッグする場合、デバッグビューのorg.eclipse.equinox.launcher.Mainフィールドをクリックして、すべてのスレッドを停止できます。

次に、そこから、スレッドごとにスタックトレースを確認し、thredrunメソッドに進みます。

これが役立つ場合とそうでない場合があります。

ブライアンが言ったように、「誰がスレッドを作成したか」を簡単に識別する唯一の方法であるため、スレッドに名前を付けることをお勧めします。

于 2009-08-04T12:57:12.827 に答える
0

残念ながらそうではありません。Eclipse内では、すべてのブロックスレッドが表示されますが、それらのスタックトレースは内部状態のみを反映しており、(明らかに)作成場所に関する情報を開示していません。また、(変数ビューを使用して)オブジェクトの内部を見ると、それ以上のヒントを引き出すことができませんでした。

于 2009-08-04T12:50:00.663 に答える