Відповіді:
Щоб отримати ітерабельний набір:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
Отримати ручку до кореня 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 () кілька разів, поки масив не буде достатньо великим, щоб містити всі записи.
rootGroup
, ви повинні використовувати new Thread[rootGroup.activeCount()+1]
. activeCount()
може бути нульовим, і якщо він є, ви наткнетеся на нескінченний цикл.
Так, погляньте на отримання списку тем . Багато прикладів на цій сторінці.
Це потрібно робити програмно. Якщо ви просто хочете, щоб список в Linux був принаймні, ви можете просто скористатися цією командою:
kill -3 processid
і VM зробить потік дамп для stdout.
Ви можете отримати багато інформації про теми з ThreadMXBean .
Викличте статичний метод ManagementFactory.getThreadMXBean (), щоб отримати посилання на MBean.
Ви подивилися на jconsole ?
Тут буде перераховано всі потоки, що працюють для певного процесу Java.
Ви можете запустити jconsole з папки бін JDK.
Ви також можете отримати повний слід стека для всіх потоків, натиснувши Ctrl+Break
в Windows або відправивши kill pid --QUIT
в Linux.
Користувачі Apache Commons можуть використовувати ThreadUtils
. Поточна реалізація використовує попередньо окреслений підхід групи ниток ходу.
for (Thread t : ThreadUtils.getAllThreads()) {
System.out.println(t.getName() + ", " + t.isDaemon());
}
У 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();
}
Set<Thread> 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; i<nt; 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; i<ng; i++) {
listThreads(groups[i], indent + " ");
}
}
Щоб отримати список потоків та їх повний стан за допомогою терміналу, ви можете скористатися командою нижче:
jstack -l <PID>
Який PID - це ідентифікатор процесу, що працює на вашому комп’ютері. Щоб отримати ідентифікатор процесу вашого Java-процесу, ви можете просто запустити jps
команду.
Крім того, ви можете проаналізувати ваш дамп потоку, який виробляється jstack в TDAs (Thread Dump Analyzer), такий інструмент для швидкої прошивки чи спотифікації потоку .