Поиск имен активных потоков в пуле потоков: ExecutorService в Java - PullRequest
0 голосов
/ 31 мая 2018

Итак, я запускаю службу исполнителя и хотел бы знать Имена или идентификаторы потоков всех активных / незанятых потоков.

ExecutorService service = Executors.newCachedThreadPool(ThreadFactory threadFactory)

Мне не нужно знать количество, но фактические имена / идентификаторы всех активных потоков в моей службе исполнителя.Мне нужно идентифицировать потоки любым способом, потому что я планирую реализовать свою собственную ThreadFactory с соответствующим соглашением об именах.

Например, если мои активные потоки - T0, T1, T3, моя фабрика потоков будет называть следующий потоккак Т2.Но я не могу найти способ получить информацию об активных темах.Как я могу это сделать?

PS: Любые другие методы также будут оценены.Например, допустим, у меня все в порядке с темами с именами от T0 до T50.Я просто хочу, чтобы моя текущая фабрика потоков присваивала любое имя от T0 до T50, чтобы поток с тем же именем не был активным или неактивным.

Ответы [ 3 ]

0 голосов
/ 31 мая 2018

Подключитесь к запущенной программе через jconsole или jvisual vm.Он выдаст вам все запущенные потоки и их имена.

0 голосов
/ 31 мая 2018

Я был настолько свободен, чтобы создать тебе образец того, что я бы сделал.Однако я не смог проверить это:

public class CachingThreadFactory implements ThreadFactory{
    // amount of active threads at max
    private static final int THREAD_POOL_MAX_SIZE = 8;

    // interval in milliseconds of the clean up task
    private static final int CLEAN_UP_INTERVAL = 2000;

    // the actual cache
    private final Thread[] cachedThreads = new Thread[THREAD_POOL_MAX_SIZE];

    // clean up task definition
    {
        new Timer().scheduleAtFixedRate(new CleanUpTask(), 0, CLEAN_UP_INTERVAL);
    }

    @Override
    public synchronized Thread newThread(Runnable r){
        for(int i = 0; i < cachedThreads.length; i++){
            if(cachedThreads[i] == null){
                return cachedThreads[i] = new Thread(r, "T" + i);
            }
        }
        return null;
    }

    private final class CleanUpTask extends TimerTask{
        @Override
        public void run(){
            synchronized(CachingThreadFactory.this){
                for(int i = 0; i < cachedThreads.length; i++){
                    final Thread thread = cachedThreads[i];
                    if(thread != null && !thread.isAlive()){
                        cachedThreads[i] = null; // unset
                    }
                }
            }
        }
    }
}

Эта фабрика кэширует каждый поток, который она создает в массиве.Затем он запускает cleanUpTask асинхронно, который проверяет, живы ли потоки в массиве (если есть).Если нет, то они удаляются.

Метод newThread выполняет итерацию по кэшу, чтобы найти индекс, который еще не взят, а затем использует этот индекс для создания имени этого Thread.Если нет свободного места, он просто возвращает null.

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

0 голосов
/ 31 мая 2018

вызовите вместо

Executors.newCachedThreadPool(ThreadFactory threadFactory)

и передайте вашу реализацию ThreadFactory.Там вы можете управлять именами потоков во время создания потока.

...