2012-05-04 3 views
6

私がjava.lang.Threadから理解できる限り、 "How to access a Runnable object by Thread?"と "Get current instance of Runnable"のようにstackoverflowに掲載されている他の質問からThreadに埋め込まれたRunnableオブジェクトの参照を取得することはできません。スレッドに埋め込まれたRunnableを取得できないのはなぜですか?

この可能性があるシナリオは、別のクラスまたはインターフェイスで定義されたメソッドをオーバーライドしているためにシグネチャを変更できないメソッドを実装するときに役立ちます。現在Threadに埋め込まれているタイプRunnableです。私たちはこの方法に含まれる操作さを確保したいときは、状況でも有用である可能性

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

:私たちは例のために持っていた場合は

は、この方法では、我々はこのような何かを行うことができThreadクラスでgetRunnableと呼ばれますあるスレッドだけが実行し、他のスレッドは実行しません。

Java開発者がからRunnableインスタンスを取得することを許可しないと決めた理由があるのでしょうか、それとも通知される価値の欠如ですか?その選択肢の背後に理由がないと思うが、欠落した機能として通知する価値はない場合は、上記のシナリオではどのような戦略を使用しますか?

+0

? –

+2

@KirkWoll、 'null'? –

+4

あなたの例のように 'instanceof'の結果に分岐することは、決して良い考えではありません。 – NPE

答えて

11

だから私は思っていた、Java開発者はそれはおそらくない要件でしたスレッド

からのRunnableインスタンスを取得することができないようにすることを決めた理由を具体的な理由があります。 Runnable自体は、それ自身のクラスを識別できなければならないので、その情報を取得する必要があるという考えは奇妙です。また、他のスレッドが別のスレッドで実行中のクラスへのアクセスを持たないように保護することもできます。

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

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

5

カップルは、あなたがこの問題を回避するために取ることができるアプローチがあります。

Map<Thread, Runnable>またはThreadLocal<Runnable>のいずれか)、それらを実行しているThread秒にごRunnable秒のマッピングをキープ
使用リフレクションThreadからRunnableにアクセスするには:

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; 
} 
0

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

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

出力:

トレースするjava.lang。`main`方法でメインスレッドの "実行可能" になりますどのようなスレッド

トレースcom.emc.multithreading.RunnableDemo

トレースjava.lang.Threadの

関連する問題