有没有办法获取当前JVM中所有运行中线程的列表(包括未由我的类启动的线程)?
是否还可以在列表中获取所有线程的Thread
和Class
对象?
我希望能够通过代码实现此操作。
有没有办法获取当前JVM中所有运行中线程的列表(包括未由我的类启动的线程)?
是否还可以在列表中获取所有线程的Thread
和Class
对象?
我希望能够通过代码实现此操作。
获取可迭代的集合:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
性能:12个线程,耗时0毫秒(Azul JVM 16.0.1,Windows 10,Ryzen 5600X)。
获取根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()
可能为零,如果是这样,您将陷入无限循环中。 - jmiserez是的,看一下获取线程列表。该页面上有很多示例。
这是以编程方式完成的。如果你只想在Linux上列出一个列表,至少可以使用以下命令:
kill -3 processid
此时虚拟机将在标准输出中输出线程转储信息。
您看过 jconsole 吗?
它可以列出特定 Java 进程中所有正在运行的线程。
您可以从 JDK bin 文件夹启动 jconsole。
您也可以通过在 Windows 上按下 Ctrl + Break
或在 Linux 上发送 kill pid --QUIT
来获取所有线程的完整堆栈跟踪。
Thread.getAllStackTraces().keySet().forEach((t) -> System.out.println(t.getName() + "\nIs Daemon " + t.isDaemon() + "\nIs Alive " + t.isAlive()));
如果需要,您可以明显获得更多的线程特性。
Apache Commons用户可以使用ThreadUtils
。当前实现使用先前概述的遍历线程组方法。
for (Thread t : ThreadUtils.getAllThreads()) {
System.out.println(t.getName() + ", " + t.isDaemon());
}
jstack -l <PID>
在您的计算机上运行的进程的ID是哪个 <PID>
。要获取Java进程的进程ID,您可以简单地运行jps
命令。
此外,您还可以分析由jstack生成的线程转储,例如使用TDAs(线程转储分析器)中的fastthread或Spotify线程分析工具。
获取由主线程启动的线程列表的代码片段:
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
// Get a snapshot of the list of all threads
Thread[] threads = Thread.getThreads()