これは珍しいことです:最初に現在実行中のスレッドを生成したクラス/メソッドを取得できますか?スタックトレースの実行は、当然のことながら、現在のスレッドの呼び出しスタックの最上部で停止します。現在のスレッドが生成されたクラスとメソッドの名前を取得できますか?
答えて
はい、できます: 私は2つの方法を提供します:1つの標準と1つのセミハック。
ほとんどの回答は、Javaの組み込み関数であると考えられていますが、外に出ています。
セキュリティマネージャをインストールしてSecurityManager.getThreadGroup()
を上書きすると、スタックトレースを簡単に取得できます。オプションで、残りのメソッドもオーバーライドすることで、セキュリティチェックの残りの部分を無効にすることもできます。
ハッキーワン:メインスレッド(mainという名前のメソッドとmain(String [] args)メソッド)でInheritableThreadLocalをインストールします。保護されているを上書きすると、完了です。
注:作成中のスレッドと親スレッド(参照)のスタックトレースは取得できますが、問題をトレースするのに十分なはずです。
私はそれがどれほど簡単かを示すために簡単なサンプルを書くことにしました: ここで結果を見ることができます。サンプルを見ると、私はこのサイトに投稿した最もエレガントなソリューションだと思います。ほとんどがb/cですが、それは明らかではありませんがシンプルでスマートです。
package bestsss.util;
import java.util.Arrays;
public class StackInterceptor extends InheritableThreadLocal<StackTraceElement[]>{
public static final StackInterceptor instance;
static{
instance = new StackInterceptor();
instance.set(new Throwable().getStackTrace());
}
@Override
protected StackTraceElement[] childValue(StackTraceElement[] parentValue) {
return new Throwable().getStackTrace();
}
//test//
public static void main(String[] args) {
Runnable r= new Runnable(){
@Override
public void run() {
System.out.printf("%s - creation stack: %s%n", Thread.currentThread(), Arrays.toString(instance.get()).replace(',', '\n'));
}
};
Thread t1 = new Thread(r, "t1");
//spacer
Thread t2 = new Thread(r, "t2");
t1.start();
t2.start();
}
}
Thread[t1,5,main] - creation stack: [bestsss.util.StackInterceptor.childValue(StackInterceptor.java:13) bestsss.util.StackInterceptor.childValue(StackInterceptor.java:1) java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:334) java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:242) java.lang.ThreadLocal.createInheritedMap(ThreadLocal.java:217) java.lang.Thread.init(Thread.java:362) java.lang.Thread.(Thread.java:488) bestsss.util.StackInterceptor.main(StackInterceptor.java:25)] Thread[t2,5,main] - creation stack: [bestsss.util.StackInterceptor.childValue(StackInterceptor.java:13) bestsss.util.StackInterceptor.childValue(StackInterceptor.java:1) java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:334) java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:242) java.lang.ThreadLocal.createInheritedMap(ThreadLocal.java:217) java.lang.Thread.init(Thread.java:362) java.lang.Thread.(Thread.java:488) bestsss.util.StackInterceptor.main(StackInterceptor.java:27)]
幸運と幸せなハッキング。
InheritableThreadLocalのソリューションは美しいものです。 main()のソースが利用できない場合(例えば、アプリケーションサーバの場合) –
main()は最初の(通常はermほぼ)メソッドですアプリケーションで呼び出すことができます。使用できない場合は、threadLocalを初期化した後、生成されたすべての子(およびグランド・チャイルド++)スレッドがトレース可能になります。要するに、できるだけ早くinit部分を行います。 – bestsss
通常、
スレッドの作成を制御できる場合は、スレッドをサブクラス化して、スタックトレースをコンストラクタに登録できます。もちろん、これはスレッドを作成したメソッドであり、必ずしも.start()
と呼ばれるものではありません。したがって、このメソッドをよりよくオーバーライドします。
しかし、多くの場合、どのメソッドがスレッドを開始したのではなく、実行者のにタスクをサブミットしたかを知りたいスレッドプールを使用します。
プールを制御する場合、threadFactoryを制御することは不思議ではないので、スレッドファクトリです。 – bestsss
@bestsss:はい。私の指摘は、このスレッドファクトリメソッドは通常、**あなたが本当に知りたい**ではないことです。誰が(どのメソッドを)スレッドプールに(または誰がその実行可能オブジェクトを作成して)送信したのかを知りたいでしょう。このために、スレッドプールはすべてのタスクにメタデータを追加する必要があり、何らかの方法でこれを取得する手段を提供します。 –
ŭlo、タスクを装飾するために 'AbstractExecutorService'に' newTaskFor(...) 'があります。逆に、第1のタスクがいつスレッドを生成したかを知ることは非常に重要である。理由は分かりませんが、新しく作成されたスレッドは親からかなり継承され、リークを防ぐために(ClassLoader、AccessControlContext、ThreadGroupなど)、徹底したThreadFactoryを使用します。 – bestsss
いいえ、不可能です。おそらく、これを達成する方法は、AspectJを使用してbefore
アドバイスをThread.start()
にすることです...もちろん、Thread
、パッチJDKコード(別のブートCLASSPATH)などをサブクラス化できますが、AspectJは最もポータブルでエレガントなソリューションです。
doh、それほど多くの作業:) – bestsss
- 1. AS3で現在のクラスとメソッドの名前を取得
- 2. 現在のクラスの名前を取得しますか?
- 3. 静的メソッドで現在のクラスの名前を取得するには?
- 4. 現在のユーザーの名前を取得
- 5. 現在実行中のメソッドの名前を取得
- 6. 次のdivを現在のクラス名と同じクラス名で取得する
- 7. フィルタの前に発生する現在のアクションを取得できますか?
- 8. Delphi 7で現在のメソッドの名前を取得する方法は?
- 9. VB.netで変数名の型と現在のクラスまたはメソッドの値を取得する方法は?
- 10. 現在のメソッドは、どのメソッドが呼び出されたかを知ることができますか?
- 11. clojureでは、どのようにして現在の名前空間のファイル名を取得できますか?
- 12. メソッドが定義されたクラスを取得しますか?
- 13. スニペットで現在の名前空間を取得
- 14. 現在のレイアウトの名前を取得する方法は?
- 15. 現在の関数の名前を取得するには?
- 16. UIPanGestureRecognizerメソッドで現在のタッチポイントと以前のタッチポイントを取得する方法は?
- 17. Flex:指定されたClassオブジェクト、それが表すクラスの名前を取得
- 18. パッケージを含む現在のクラス名を取得する
- 19. Funcで実行される呼び出されたメソッドの名前の取得
- 20. async関数から現在のメソッド名を取得しますか?
- 21. 生成されたgoファイルの名前
- 22. 現在のメソッドの名前またはシグネチャをNSStringに取得する方法は?
- 23. 鼻を使ってセットアップで現在のテストの名前を取得します
- 24. Windowsスペシャルフォルダの現在の名前を取得
- 25. PHP現在のディレクトリの名前を取得
- 26. 現在のクラスを取得する
- 27. 解析されたファイルの名前を取得しますか?
- 28. 名前付きBeanの作成中にエラーが発生しました:スコープ 'request'が現在のスレッドで有効ではありません
- 29. 現在のモジュール名を取得する
- 30. JUNITの@Beforeで現在実行中の@Testメソッドの名前を取得します。
私はあなたが何か重要なものではなく、いくつかのハッキングデバッグのためにこれをやってくれることを願っています。 –
ハハ、あなたは正しく仮定します。 --D – Wilco
関連していますが(同じではありません):[Javaでスタックトレースを作成する](http://stackoverflow.com/questions/6270256/forging-a-)-私はこのパスを開始してから私の鼻を止めていません。 stack-trace-in-java) –