JavaRush /Java блог /Архив info.javarush /Как получить список мертвых нитей из группы ThreadGroup? ...
Dead_MOPO3
36 уровень
Москва

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

Статья из группы Архив info.javarush
Ну собственно в названии и сам вопрос. Кто разобрался, подскажите. Нашел такой вариант, но он мне уж совсем не нравится и не работает) 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"). но подход уж слишком хардкод. добираться до приватных полей через рефлексию...
Комментарии (7)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
vampirit Уровень 40
14 марта 2017
Думал, думал, вот, что надумал:

Это невозможно. Получив доступ к полю 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
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
del
xprox4 Уровень 32
17 апреля 2016
Кто-нибудь нашел более-менее приемлемый способ получить список всех мертвых тредов?
leshak Уровень 27
11 сентября 2015