Dead_MOPO3
36 уровень
Москва

Как получить список мертвых нитей из группы ThreadGroup? level 28

Пост из группы Архив info.javarush.ru
3272 участников
Ну собственно в названии и сам вопрос. Кто разобрался, подскажите. Нашел такой вариант, но он мне уж совсем не нравится и не работает) public static void main(String[] args) { /* * For testing purposes */ ThreadGroup tg = new ThreadGroup( "MyThreadGroup" ); Thread subThread = new Thread( tg, "New Thread - Inactive" ); try { /* * GETTING THREADS - PROBABLY BETTER TO GET IT BY USING * getDeclaredFields() AND LOOPING TILL GET ONE OF TYPE * Thread[] SINCE A FUTURE VERSION MIGHT CHANGE THE NAME * BUT SINCE IS PACKAGE-LEVEL ACCESS, IT'S PROBABLY USED * ELSEWHERE IN THE PACKAGE, AND THIS IS JUST AN EXAMPLE */ Field field = tg.getClass().getDeclaredField( "threads" ); //NEED TO SUPPRESS ACCESS CHECKS field.setAccessible( true ); //EVEN IF SECURITY IS OFF YOU NEED THIS!!!! Thread[] tgThreads = ( Thread[] ) field.get( tg ); for ( int i = 0; i < tgThreads.length; i++ ) { if ( tgThreads[ i ] != null ) System.out.println( tgThreads[ i ].getName() + " = " + tgThreads[ i ].isAlive() ); } } catch (NoSuchFieldException nsfe) { nsfe.printStackTrace(); } catch (IllegalAccessException iae) { iae.printStackTrace(); } } Получается строчка Thread[] tgThreads = ( Thread[] ) field.get( tg ); не генерит мне массив. почитал, вроде можно как то залезть в System.SecurityManager и поставить ReflectPermission("suppressAccessChecks"). но подход уж слишком хардкод. добираться до приватных полей через рефлексию...
Комментарии (8)
  • популярные
  • новые
  • старые
Для того, что бы оставить комментарий вы должны авторизироваться
vampirit 40 уровень, Санкт-Петербург
14 марта 2017, 04:20
Думал, думал, вот, что надумал:

Это невозможно. Получив доступ к полю threads класса ThreadGroup мы получаем null на все завершенные нити. Значит группа удаляет все ссылки на завершенные нити, значит найти их после этого (не имея больше никаких ссылок не представляю как).

Что я понял:
1. Ссылка на нить удаляется из группы после выполнения
2. У нити удаляется ссылка на группу, после того как нить завершиться.
— все это происходить только на последней стадии (TERMINATED)

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

Другой вариант, это когда мы заранее знаем, что нам надо иметь список нитей. Тогда при создании объекта, заносим его ссылку в лист. Можно в конструкторе нити, а если нить анонимная, то в run. Ну либо Завести лист про который нити не знают и ручками после создания нити добавлять, главное сохранить ссылку на нить.

package test;

import java.util.*;

public class ThreadGroupsTut {

    private final static Map <Thread, Thread.State> threadMap = new HashMap<>();


    public static void main(String[] args) throws InterruptedException {
        ThreadGroup group = new ThreadGroup("My");
        ThreadTerminated terminated = new ThreadTerminated(group, "Terminated ");
        ThreadAlive alive = new ThreadAlive(group, "Alive");


        Thread deamon = new Thread(){

            @Override
            public void run() {
                while (true){
                    for (Map.Entry<Thread,State> t : threadMap.entrySet()) {
                        Thread thread = t.getKey();
                        if (thread.getState() != t.getValue()){
                            System.out.println(String.format("%s : %s : %s",
                                    thread.getThreadGroup(), 
apache888 40 уровень, Одесса
21 ноября 2016, 20:36
Getting a list of all threads in a specific state
The getState( ) method on Thread tells you if the thread is runnable or if it is blocked waiting on something. There are six states, defined by the Thread.State enum:

NEW. The thread has been created, but hasn't run yet.
TERMINATED. The thread has run to completion, but hasn't been deleted yet by the JVM.
RUNNABLE. The thread is running.
BLOCKED. The thread is blocked waiting on a lock (such as in a synchronized block or method).
WAITING. The thread is waiting until another thread calls notify( ).
TIMED_WAITING. The thread is either waiting or in a sleep( ).
During debugging it can be useful to monitor which threads are in which states. To get a list of threads in a specific state, get a list of all threads and extract the ones in the state you want.
Thread[] getAllThreads( final Thread.State state ) {
    final Thread[] allThreads = getAllThreads( );
    final Thread[] found = new Thread[allThreads.length];
    int nFound = 0;
    for ( Thread thread : allThreads )
        if ( thread.getState( ) == state )
            found[nFound++] = thread;
    return java.util.Arrays.copyOf( found, nFound );
}
Adeptius 41 уровень, Киев
4 июля 2016, 16:34
del
Yurets_Y 40 уровень, Киев
10 июня 2016, 16:05
Код проверял, все работает, через рефлекцию методом .getClass().getDeclaredField(«threads»); возвращает массив Thread[] threads, хранящий ссылки на все потоки, вот только обработанные потоки имеют ссылку null, а из null как говорят и взятки гладки, ни имени, ни свойств. Как вариант можно при запуске потоков дописать код, который будет сохранять все ссылки на потоки. а потом удалив из массива всех потоков, активные потоки получить список мертвых, но такую конструкцию можно соорудить только если ты автор всего кода, а не просто пытаешься в готовом коде выполнить счет активных и неактивных потоков группы. Для живых потоков метод работает, для мертвых нет.
xprox4 32 уровень
17 апреля 2016, 16:06
Кто-нибудь нашел более-менее приемлемый способ получить список всех мертвых тредов?
TtTt 34 уровень, Киев
18 апреля 2016, 12:49
Не проверял, но есть теория.
Для того чтобы получить мертвые нити нужно: Список всех нитей — Список всех живых нитей = Список мертвых нитей.
Список всех нитей.
Создать поток демон, который будет заполнять общий список все нитей по принципу я тебя не знаю — давай к нам
Живые нити
Thread[] temp = new Thread[thG.activeCount()];
thG.enumerate(temp);

Где thG это объект ThreadGroup
Если у кого хватит опыта реализовать, то большое спасибо.
leshak 27 уровень, Витебск, Беларусь
11 сентября 2015, 00:49
Dead_MOPO3 36 уровень, Москва
11 сентября 2015, 23:05
та читал я это. но там в методе, который должен, якобы, вернуть список всех тредов, он возвращает только живые