Получить все потоки, которые работают с указанным Runnable - PullRequest
2 голосов
/ 27 июня 2011

У меня есть один Runnable, который используется более чем одним потоком:

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

Как мне получить все потоки, созданные с помощью myRunnable?

(Конечно, примерЯ создаю новые потоки с myRunnable в нескольких местах в разных классах.)

Вариант использования (по запросу): MyWorkerOfMyPage - это задержанный работник, связанный с страницей.Если пользователь покидает эту страницу (например, переходя на другую страницу), все потоки, принадлежащие MyWorkerOfMyPage, должны быть изящно уничтожены, поскольку их результат больше не нужен.

Ответы [ 4 ]

4 голосов
/ 27 июня 2011

Как уже говорилось, лучший способ это отследить самостоятельно. Это заставляет вас получить четкое представление о том, что вы делаете. Хорошая вещь, если вы работаете с потоками ... хммм ... хорошая вещь в каждом случае;).

Но если вы действительно хотите обнаружить потоки, вы можете использовать отражение с классом 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;
    }
}
4 голосов
/ 27 июня 2011

Лучший способ сделать это - отследить это самостоятельно. Например, используйте глобальный синглтон, который запускает потоки и отслеживает, какие из них вы запустили.

1 голос
/ 27 июня 2011

Хотя мои первые мысли совпадают с @ Bengt, возможно, вы могли бы использовать Class.isAssignableFrom, если у вас есть список исполняемых объектов, и вы просто хотите знать, какие из них используют ваш интерфейс.

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

0 голосов
/ 27 июня 2011

В Java нет простого способа найти все места, на которые ссылается объект, это то, что вы должны поддерживать коллекцию себя.

Если вы хотите знать это статически, вы можете найти использование в вашем идеале.

Если вы хотите узнать это динамически, вы можете запустить Runnable, чтобы добавить поток в коллекцию (и удалить его, когда закончите)

Вообще говоря, разработчик должен создавать потоки только намеренно. разработчик должен знать, когда он создает поток и что будут делать эти потоки. Это не то, что вы должны пытаться отслеживать во время выполнения, если у вас хороший дизайн.

...