4

ドキュメントや、「スレッドでRunnableオブジェクトにアクセスする方法」や「Runnableの現在のインスタンスを取得java.lang.Threadする」など、stackoverflowに投稿された他の質問から理解できる限り、埋め込まれたオブジェクトの参照を取得することはできません。で。RunnableThread

この可能性があると便利なシナリオは、別のクラスまたはインターフェイスで定義されたメソッドをオーバーライドしているためにシグネチャを変更できないメソッドを実装する場合です。Runnable組み込みのタイプに応じて異なる操作を実行する必要があります。現在Thread

たとえばgetRunnableThreadクラスで呼び出されるメソッドがある場合、次のようなことができます。

if (Thread.currentThread().getRunnable() instanceof Type1) {
  // do something...
} else {
  // do something else...
}

これは、メソッドに含まれる操作が特定のスレッドによってのみ実行され、他のスレッドによっては実行されないようにする場合にも役立ちます。

Runnableだから私は疑問に思っていました、Java開発者がからインスタンスを取得することを許可しないことを決定した特定の理由がありますかThread、それとも通知する価値のある不足している機能ですか?その選択の背後に理由がないと思うが、機能が不足していることを通知する価値がない場合、上記のシナリオでどのような戦略を使用しますか?

4

3 に答える 3

9

だから私は疑問に思っていましたが、Java開発者がスレッドからRunnableインスタンスを取得することを許可しないことにした特定の理由がありますか?

それはおそらく要件ではありませんでした。それRunnable自体が自身のクラスを識別できる必要があるため、その情報を取得する必要があるという考えは奇妙です。また、他のスレッドが別のスレッドで実行されているクラスにアクセスできないようにするための保護にもなります。

Runnableアプリケーションの他の部分から電流にアクセスする必要がある場合は、を使用することをお勧めしThreadLocal<Runnable>ます。run()メソッドでは、それを設定してから、他のクラスで取得できます。ThreadLocalただし、グローバルにアクセスできる場所に配置する必要があります。

Runnableまた、現在のスタックトレースを処理して、さらにハックである囲んでいるクラスを把握することもできますが、それは機能します。

于 2012-05-04T17:02:00.543 に答える
4

これを回避するために取ることができるいくつかのアプローチがあります:

を実行しているRunnablesへのマッピングを保持します(またはを使用して) リフレクションを使用して:からにアクセスします。ThreadMap<Thread, Runnable>ThreadLocal<Runnable>
RunnableThread

private static final Field target;
static {
    Field f = null;
    try {
        f = Thread.class.getDeclaredField("target");
        f.setAccessible(true);
    } catch (NoSuchFieldException e) {
        // might happen in a different version of Java (works in Java 7)
        e.printStackTrace();
    }
    target = f;
}

public static Runnable getTarget(Thread t) {
    try {
        return (Runnable) target.get(t);
    } catch (IllegalAccessException e) {
        // shouldn't happen, we already made the field accessible when we created it
        e.printStackTrace();
        }
    return null;
}
于 2012-05-04T17:09:17.157 に答える
0

間接的な方法がありますが、それが役立つかもしれません。スタックトレースを取得できます。

StackTraceElement[] stackTraceElement = thread.getStackTrace();
for(StackTraceElement e :stackTraceElement){
   System.out.println("Trace "+e.getClassName());
}

出力:

java.lang.Threadをトレースします

トレースcom.emc.multithreading.RunnableDemo

java.lang.Threadをトレースします

于 2017-05-10T09:47:27.253 に答える