2

複数のスレッドで使用される Runnable が 1 つあります。

Runnable myRunnable = new MyWorker();
Thread one = new Thread(myRunnable);
Thread two = new Thread(myRunnable);
one.start();
two.start();

で作成されたすべてのスレッドを取得するにはどうすればよいmyRunnableですか?

(もちろん、例は単純化されてmyRunnableいます。異なるクラスのいくつかの場所で新しいスレッドを作成します。)

ユースケース (要求に応じて):MyWorkerOfMyPageページにバインドされた遅延ワーカーです。ユーザーがこのページを離れた場合 (たとえば、別のページに移動した場合)、属するすべてのスレッドMyWorkerOfMyPageは、その結果が不要になるため、不適切に強制終了する必要があります。

4

4 に答える 4

4

すでに述べたように、最善の方法はこれを自分で追跡することです。これにより、自分が何をしているのかを明確に理解することができます。スレッドで作業する場合は良いことです...うーん...すべての場合に良いことです;)。

しかし、本当にスレッドを検出したい場合は、 Thread クラスでリフレクションを使用して必要な情報を取得できます。最初にメソッド「getThreads」をアクセス可能にして実行中のすべてのスレッドを取得し、次にフィールド「target」をアクセス可能にしてスレッドのランナブルを取得します。

サンプルプログラムを次に示します (ただし、実際のアプリケーションで使用しないことをお勧めます。開始するスレッドを確認する必要があります。将来の JDK との互換性が損なわれる可能性があり、移植性が損なわれる可能性があります ...):

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws Exception {
        Runnable myRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("Start: " + Thread.currentThread().getName());
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        };
        Thread one = new Thread(myRunnable);
        Thread two = new Thread(myRunnable);
        one.start();
        two.start();

        List<Thread> threads = getThreadsFor(myRunnable);
        for (Thread thread : threads)
            System.out.println("Found: " + thread.getName());
    }

    private static List<Thread> getThreadsFor(Runnable myRunnable) throws Exception {
        Method getThreads = Thread.class.getDeclaredMethod("getThreads");
        Field target = Thread.class.getDeclaredField("target");
        target.setAccessible(true);
        getThreads.setAccessible(true);
        Thread[] threads = (Thread[]) getThreads.invoke(null);
        List<Thread> result = new ArrayList<Thread>();
        for (Thread thread : threads) {
            Object runnable = target.get(thread);
            if (runnable == myRunnable)
                result.add(thread);
        }
        return result;
    }
}
于 2011-06-27T14:03:35.857 に答える
4

The best way to do this is to track this yourself. Use a global singleton for instance that launches the threads and track which ones you started.

于 2011-06-27T09:52:19.707 に答える
1

私の最初の考えは@Bengtの線に沿っていますが、実行可能なリストがあり、どれがインターフェイスを使用しているかを知りたい場合は、おそらく Class.isAssignableFrom を使用できます。

http://download.oracle.com/javase/6/docs/api/java/lang/Class.html

于 2011-06-27T10:05:16.460 に答える
0

Java では、オブジェクトが参照されているすべての場所を見つける簡単な方法はありません。それは、自分自身のコレクションを維持する必要があるものです。

これを静的に知りたい場合は、IDE で使用法を見つけることができます。

これを動的に知りたい場合は、Runnable にスレッドをコレクションに追加させることができます (終了したら削除します)。

一般に、開発者は意図的にスレッドを作成する必要があります。つまり、開発者はいつスレッドを作成し、それらのスレッドが何をするのかを知っている必要があります。優れた設計があれば、実行時に追跡する必要はありません。

于 2011-06-27T09:55:49.190 に答える