如何获取 Java 进程中的线程数

如何查看 Java 进程中的线程数?

125905 次浏览

There is a static method on the Thread Class that will return the number of active threads controlled by the JVM:

Thread.activeCount()

Returns the number of active threads in the current thread's thread group.

Additionally, external debuggers should list all active threads (and allow you to suspend any number of them) if you wish to monitor them in real-time.

java.lang.Thread.activeCount()

It will return the number of active threads in the current thread's thread group.

docs: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#activeCount()

Useful tool for debugging java programs, it gives the number of threads and other relevant info on them:

jconsole <process-id>

    public class MainClass {


public static void main(String args[]) {


Thread t = Thread.currentThread();
t.setName("My Thread");


t.setPriority(1);


System.out.println("current thread: " + t);


int active = Thread.activeCount();
System.out.println("currently active threads: " + active);
Thread all[] = new Thread[active];
Thread.enumerate(all);


for (int i = 0; i < active; i++) {
System.out.println(i + ": " + all[i]);
}
}
}

ManagementFactory.getThreadMXBean().getThreadCount() doesn't limit itself to thread groups as Thread.activeCount() does.

I have written a program to iterate all Threads created and printing getState() of each Thread

import java.util.Set;


public class ThreadStatus {
public static void main(String args[]) throws Exception{
for ( int i=0; i< 5; i++){
Thread t = new Thread(new MyThread());
t.setName("MyThread:"+i);
t.start();
}
int threadCount = 0;
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for ( Thread t : threadSet){
if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup()){
System.out.println("Thread :"+t+":"+"state:"+t.getState());
++threadCount;
}
}
System.out.println("Thread count started by Main thread:"+threadCount);
}
}


class MyThread implements Runnable{
public void run(){
try{
Thread.sleep(2000);
}catch(Exception err){
err.printStackTrace();
}
}
}

Output:

java ThreadStatus


Thread :Thread[MyThread:0,5,main]:state:TIMED_WAITING
Thread :Thread[main,5,main]:state:RUNNABLE
Thread :Thread[MyThread:1,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:4,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:2,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:3,5,main]:state:TIMED_WAITING
Thread count started by Main thread:6

If you remove below condition

if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup())

You will get below threads in output too, which have been started by system.

Reference Handler, Signal Dispatcher,Attach Listener and Finalizer.

Generic solution that doesn't require a GUI like jconsole (doesn't work on remote terminals), ps works for non-java processes, doesn't require a JVM installed.

ps -o nlwp <pid>

Using Linux Top command

top -H -p (process id)

you could get process id of one program by this method :

ps aux | grep (your program name)

for example :

ps aux | grep user.py

Get number of threads using jstack

jstack <PID> | grep 'java.lang.Thread.State' | wc -l

The result of the above code is quite different from top -H -p <PID> or ps -o nlwp <PID> because jstack gets only threads from created by the application.

In other words, jstack will not get GC threads

$ ps -p <pid> -lfT | wc -l

You can get the pid using:

$ top or $ ps aux | grep (your program name)

To get all threads, not only for one process

$ ps -elfT | wc -l

This is for centOS / Red Hat machines, it may or not work on other linux machines

Another way: Get the process name using jps command and use that in below script snippet:

# Get the process id
processPid=$(jps -l | grep "Process Name" | awk '{print $1}');
# Use process id to get number of threads using ps command
ps -M $processPid| wc -l

Tested on macOS.