Java получить все потоки

Получить список всех потоков, работающих в настоящее время в Java

Можно ли как-нибудь получить список всех запущенных потоков в текущей JVM (включая потоки, не запущенные моим классом)?

Можно ли также получить объекты Thread и Class всех потоков в списке?

Я хочу быть в состоянии сделать это с помощью кода.

Чтобы получить повторяемый набор:

SetThread> threadSet = Thread.getAllStackTraces().keySet();

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

@ Эдди Это предположение из здравого смысла, или ты делал эксперименты? «значительно медленнее», говорите вы; насколько медленнее? Стоит ли оно того? Я ставлю под сомнение любые попытки сделать код хуже для эффективности. Если у вас есть требования к эффективности и инфраструктура для количественного измерения эффективности, тогда я согласен с тем, что люди делают код хуже, потому что они, кажется, знают, что делают. Посмотрите на корень всего зла, согласно Дональду Кнуту.

Я не рассчитывал эти конкретные альтернативы, но я работал с другими средствами Java, собирающими трассировки стека, а не просто список потоков. Влияние на производительность очень сильно зависит от того, какую JVM вы используете (например, JRockit против Sun JVM). Это стоит измерить в вашем конкретном случае. Будет ли это влиять на вас, зависит от вашего выбора JVM и от того, сколько у вас потоков. Я обнаружил, что получение всех трассировок стека с помощью ThreadMXBean.dumpAllThreads для примерно 250 потоков занимает 150-200 мсек при получении только списка потоков (без трасс), который невозможно измерить (0 мсек).

В моей системе (Oracle Java 1.7 VM) быстрая проверка показывает, что этот метод в 70–80 раз медленнее, чем альтернатива ниже. Следы стека и отражение относятся к самым тяжелым операциям Java.

@thejoshwolfe: Конечно, удобочитаемость является важным фактором, поэтому не нужно микрооптимизировать и т. д. Однако я провел исследование, когда писал небольшой монитор производительности приложений. Для такого рода инструментов необходим минимальный отпечаток производительности для получения надежных данных, поэтому я выбрал метод без использования стека.

Получить дескриптор к корню ThreadGroup , как это:

ThreadGroup rootGroup = Thread.currentThread().getThreadGroup(); ThreadGroup parentGroup; while ((parentGroup = rootGroup.getParent()) != null)  rootGroup = parentGroup; > 

Теперь enumerate() повторно вызовите функцию в корневой группе. Второй аргумент позволяет получить все потоки рекурсивно:

Thread[] threads = new Thread[rootGroup.activeCount()]; while (rootGroup.enumerate(threads, true ) == threads.length)  threads = new Thread[threads.length * 2]; > 

Обратите внимание, как мы неоднократно вызываем enumerate (), пока массив не станет достаточно большим, чтобы содержать все записи.

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

@thejoshwolfe: На самом деле, я согласен — я думаю, что ваш ответ намного лучше, и, вероятно, это был бы принятый ответ в первую очередь, если бы не было одного года с опозданием. Если ОП по-прежнему часто посещает SO, что он, по-видимому, делает, ему бы посоветовали не принять мой ответ и скорее принять ваш.

Обратите внимание, что для чего-либо, кроме rootGroup , вы должны использовать new Thread[rootGroup.activeCount()+1] . activeCount() может быть ноль, и если это так, вы столкнетесь с бесконечным циклом.

+1 за этот недооцененный ответ, так как он гораздо больше подходит для целей мониторинга ИМХО. Присущие ему гоночные условия не имеют большого значения для мониторинга. Однако, как показал какой-то быстрый и грязный тест, он примерно в 70-80 раз быстрее, чем решение на основе стековой трассировки. Для мониторинга важен небольшой отпечаток производительности, так как вы хотите, чтобы влияние на отслеживаемую систему было как можно меньшим (Гейзенберг наносит удар снова 🙂 Для отладки, когда вам может потребоваться более надежная информация, может использоваться метод стековой трассировки. существенный. Кстати, решение MxBean даже медленнее, чем использование стековых трасс.

Да, взгляните на получение списка тем . Много примеров на этой странице.

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

и виртуальная машина сделает дамп потока в стандартный вывод.

cletus действительно верен — команда kill -3 будет направлять дамп на стандартный вывод независимо от того, что должен означать сигнал. Я хотел бы рассмотреть возможность использования Jstack вместо.

Вы можете получить много информации о потоках из ThreadMXBean .

Вызовите статический метод ManagementFactory.getThreadMXBean (), чтобы получить ссылку на MBean.

Вы смотрели на jconsole ?

Это перечислит все потоки, работающие для определенного процесса Java.

Вы можете запустить jconsole из папки bin JDK.

Вы также можете получить полную трассировку стека для всех потоков, нажав Ctrl+Break в Windows или отправив kill pid —QUIT в Linux.

Пользователи Apache Commons могут использовать ThreadUtils . Текущая реализация использует ранее описанный подход с использованием групповых потоков.

for (Thread t : ThreadUtils.getAllThreads())  System.out.println(t.getName() + ", " + t.isDaemon()); > 

Вы можете попробовать что-то вроде этого:

Thread.getAllStackTraces().keySet().forEach((t) -> System.out.println(t.getName() + "\nIs Daemon " + t.isDaemon() + "\nIs Alive " + t.isAlive()));

и вы можете, очевидно, получить больше характеристик потока, если вам нужно.

В Groovy вы можете вызывать приватные методы

// Get a snapshot of the list of all threads Thread[] threads = Thread.getThreads()

В Java вы можете вызывать этот метод, используя отражение, если это разрешено диспетчером безопасности.

Фрагмент кода, чтобы получить список потоков, запущенных основным потоком:

import java.util.Set; public class ThreadSet  public static void main(String args[]) throws Exception Thread.currentThread().setName("ThreadSet"); for ( int i=0; i 3; i++) Thread t = new Thread(new MyThread()); t.setName("MyThread:"+i); t.start(); > SetThread> threadSet = Thread.getAllStackTraces().keySet(); for ( Thread t : threadSet) if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup()) System.out.println("Thread :"+t+":"+"state:"+t.getState()); > > > > class MyThread implements Runnable public void run() try Thread.sleep(5000); >catch(Exception err) err.printStackTrace(); > > >
Thread :Thread[MyThread:2,5,main]:state:TIMED_WAITING Thread :Thread[MyThread:0,5,main]:state:TIMED_WAITING Thread :Thread[MyThread:1,5,main]:state:TIMED_WAITING Thread :Thread[ThreadSet,5,main]:state:RUNNABLE

Если вам нужны все потоки, включая системные, которые не были запущены вашей программой, удалите условие ниже.

if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup())
Thread :Thread[MyThread:2,5,main]:state:TIMED_WAITING Thread :Thread[Reference Handler,10,system]:state:WAITING Thread :Thread[MyThread:1,5,main]:state:TIMED_WAITING Thread :Thread[ThreadSet,5,main]:state:RUNNABLE Thread :Thread[MyThread:0,5,main]:state:TIMED_WAITING Thread :Thread[Finalizer,8,system]:state:WAITING Thread :Thread[Signal Dispatcher,9,system]:state:RUNNABLE Thread :Thread[Attach Listener,5,system]:state:RUNNABLE
 public static void main(String[] args)  // Walk up all the way to the root thread group ThreadGroup rootGroup = Thread.currentThread().getThreadGroup(); ThreadGroup parent; while ((parent = rootGroup.getParent()) != null)  rootGroup = parent; > listThreads(rootGroup, ""); > // List all threads and recursively list all subgroup public static void listThreads(ThreadGroup group, String indent)  System.out.println(indent + "Group[" + group.getName() + ":" + group.getClass()+"]"); int nt = group.activeCount(); Thread[] threads = new Thread[nt*2 + 10]; //nt is not accurate nt = group.enumerate(threads, false); // List every thread in the group for (int i=0; int; i++)  Thread t = threads[i]; System.out.println(indent + " Thread[" + t.getName() + ":" + t.getClass() + "]"); > // Recursively list all subgroups int ng = group.activeGroupCount(); ThreadGroup[] groups = new ThreadGroup[ng*2 + 10]; ng = group.enumerate(groups, false); for (int i=0; ing; i++)  listThreads(groups[i], indent + " "); > >

В консоли Java нажмите Ctrl-Break . В нем будут перечислены все потоки плюс некоторая информация о куче. Это не даст вам доступ к объектам, конечно. Но это может быть очень полезно для отладки в любом случае.

Источник

Получить все запущенные потоки JVM

В этом коротком руководстве мы узнаем, как получить все запущенные потоки в текущей JVM , включая потоки, не запущенные нашим классом.

2. Используйте класс потока​

Метод getAllStackTrace() класса Thread дает трассировку стека всех запущенных потоков. Он возвращает Map , чьи ключи являются объектами Thread , поэтому мы можем получить набор ключей и просто перебрать его элементы, чтобы получить информацию о потоках.

Давайте воспользуемся методом printf() , чтобы сделать вывод более читабельным:

 SetThread> threads = Thread.getAllStackTraces().keySet();   System.out.printf("%-15s \t %-15s \t %-15s \t %s\n", "Name", "State", "Priority", "isDaemon");   for (Thread t : threads)    System.out.printf("%-15s \t %-15s \t %-15d \t %s\n", t.getName(), t.getState(), t.getPriority(), t.isDaemon());   > 

Вывод будет выглядеть следующим образом:

Name State Priority isDaemon main RUNNABLE 5 false Signal Dispatcher RUNNABLE 9 true Finalizer WAITING 8 true Reference Handler WAITING 10 true 

Как видим, кроме потока main , который запускает основную программу, у нас есть еще три потока. Этот результат может различаться в разных версиях Java.

Давайте узнаем немного больше об этих других потоках:

  • Диспетчер сигналов : этот поток обрабатывает сигналы, отправляемые операционной системой в JVM.
  • Finalizer : этот поток выполняет финализацию для объектов, которым больше не нужно освобождать системные ресурсы.
  • Обработчик ссылок : этот поток помещает объекты, которые больше не нужны, в очередь для обработки потоком Finalizer .

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

3. Используйте класс ThreadUtils из Apache Commons​

Мы также можем использовать класс ThreadUtils из библиотеки Apache Commons Lang для достижения той же цели:

Давайте добавим зависимость в наш файл pom.xml :

 dependency>   groupId>org.apache.commonsgroupId>   artifactId>commons-lang3artifactId>   version>3.10version>   dependency> 

И просто используйте метод getAllThreads() , чтобы получить все запущенные потоки:

 System.out.printf("%-15s \t %-15s \t %-15s \t %s\n", "Name", "State", "Priority", "isDaemon");   for (Thread t : ThreadUtils.getAllThreads())    System.out.printf("%-15s \t %-15s \t %-15d \t %s\n", t.getName(), t.getState(), t.getPriority(), t.isDaemon());   > 

Выход такой же, как указано выше.

4. Вывод​

Таким образом, мы изучили два метода получения всех запущенных потоков в текущей JVM .

Источник

Русские Блоги

Конкурсная ссылка А. Игра трахается Ссылка на заголовок резюме Удивительная конвергенция, этот NM — удар сокращения размера Б. Кекс трахается Ссылка на заголовок резюме Найти правила снова . я табле.

Spring Boot Project git push giteee

Не создавайте readme.md, чтобы создать совершенно пустой проект при создании проекта на Gitee $ git init Инициализированный git $ git status $ git add . $ .

Механизм копирования при записи, чтобы понять

Во-первых, копирование на запись под Linux Прежде чем объяснить механизм копирования при записи в Linux, мы должны сначала знать две функции:fork()иexec(), Обратите внимание, чтоexec()Это не конкретна.

Python Learning — марина

Только поддерживает реализацию функций, таких как функции в Python, и содержание Pickle невидимо. При чтении необходимо исходное содержание Маринованное письмо: Чтение Pickle: Уведомлени.

1 Среда развертывания

Справочник статей 1 Ввести зависимости 1.1 Удаленный импорт 1.2 Местное введение 1 Ввести зависимости 1.1 Удаленный импорт 1.2 Местное введение.

Источник

Читайте также:  (.+)
Оцените статью