286

Is there any way I can get a list of all running threads in the current JVM (including the threads not started by my class)?

Is it also possible to get the Thread and Class objects of all threads in the list?

I want to be able to do this through code.

13 Answers 13

397

To get an iterable set:

Set<Thread> threadSet = Thread.getAllStackTraces().keySet(); 

Performance: 0 ms for 12 threads (Azul JVM 16.0.1, Windows 10, Ryzen 5600X).

Sign up to request clarification or add additional context in comments.

13 Comments

While much cleaner than the other alternative proposed, this has the downside of incurring the cost of getting stack traces for all threads. If you will be using those stack traces anyway, this is clearly superior. If not, then this may be significantly slower for no gain other than clean code.
@Eddie Is that an assumption from common sense, or did you do experiments? "significantly slower" you say; how much slower? Is it worth it? I question any attempt to make code worse for the sake of efficiency. If you have an efficiency requirement and an infrastructure to measure efficiency quantitatively, then I'm ok with people making code worse, because they seem to know what they're doing. See the root of all evil according to Donald Knuth.
I haven't timed these specific alternatives, but I've worked with other Java means of gathering stack traces vs just a list of threads. The performance impact seems to depend very strongly on which JVM you are using (JRockit vs Sun JVM for example). It's worth measuring in your specific instance. Whether or not it will affect you depends on your JVM choice and on how many threads you have. I found that getting all stack traces via ThreadMXBean.dumpAllThreads for about 250 threads to take 150 - 200 msec while getting just the list of threads (without traces) to not be measurable (0 msec).
On my system (Oracle Java 1.7 VM), a quick check shows that this method is ~70..80 times SLOWER than the alternative below. Stack traces and reflection belong to the heaviest Java operations.
@thejoshwolfe: Of course, readability is an important factor, and one should not micro-optimize etc. However, I did my research while writing a small application performance monitor. For this kind of tool, a minimal performance imprint is essential to get reliable data, so I chose the stacktrace-less method.
|
89

Get a handle to the root ThreadGroup, like this:

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

Now, call the enumerate() function on the root group repeatedly. The second argument lets you get all threads, recursively:

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

Note how we call enumerate() repeatedly until the array is large enough to contain all entries.

7 Comments

I'm shocked that this strategy is so popular on the internet. My strategy is way simpler (1 line of code) and works just as well with the added bonus of avoiding race conditions.
@thejoshwolfe: Actually, I agree - I think your answer is much better, and it probably would've been the accepted answer in the first place if it wouldn't have been one year late. If the OP still frequents SO, which he apparently does, he'd be well advised to un-accept my answer and rather accept yours.
Note that for anything other than the rootGroup, you should use new Thread[rootGroup.activeCount()+1]. activeCount() could be zero, and if it is you will run into an infinite loop.
@thejoshwolfe I suppose this solution is much less expensive.
+1 for this underrated answer, as it is much more suited for monitoring purposes IMHO. Its inherent race conditions do not matter much in monitoring. However, as some quick'n'dirty test showed, it's about 70-80 times faster than the stacktrace-based solution. For monitoring, a small performance imprint is essential, as you you'll want to keep the effects on the monitored system as small as possible (Heisenberg strikes again :) For debugging, where you may need more reliable information, the stacktrace method could be essential. BTW, the MxBean solution is even slower than using stacktraces.
|
31

Yes, take a look at getting a list of threads. Lots of examples on that page.

That's to do it programmatically. If you just want a list on Linux at least you can just use this command:

kill -3 processid 

and the VM will do a thread dump to stdout.

3 Comments

kill -3? At least on my linux, that's "terminal quit". Kills, does not list.
cletus is indeed correct - a kill -3 will thread dump to stdout, regardless of what the signal is supposed to mean. I would consider using jstack instead.
getting a list of threads can’t be reached: nadeausoftware.com refused to connect.
20

You can get a lot of information about threads from the ThreadMXBean.

Call the static ManagementFactory.getThreadMXBean() method to get a reference to the MBean.

Comments

15

Have you taken a look at jconsole?

This will list all threads running for a particular Java process.

You can start jconsole from the JDK bin folder.

You can also get a full stack trace for all threads by hitting Ctrl+Break in Windows or by sending kill pid --QUIT in Linux.

4 Comments

I want to access the list within my java class
In which case look at cletus' answer.
Um, why are people voting this up when the guy said he wanted a programmatic solution?
Because the question doesn't state that. I'll edit the question to make it explicit.
15

Apache Commons users can use ThreadUtils. The current implementation uses the walk the thread group approach previously outlined.

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

Comments

14

You can try something like this:

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

and you can obviously get more thread characteristic if you need.

Comments

13

To get a list of threads and their full states using the terminal, you can use the command below:

jstack -l <PID> 

Which <PID> is the id of process running on your computer. To get the process id of your java process you can simply run the jps command.

Also, you can analyze your thread dump that produced by jstack in TDAs (Thread Dump Analyzer) such fastthread or spotify thread analyzer tool.

Comments

6

Code snippet to get list of threads started by main thread:

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(); } } } 

output:

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 you need all threads including system threads, which have not been started by your program, remove below condition.

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

Now output:

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 

Comments

5

In Groovy you can call private methods

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

In Java, you can invoke that method using reflection provided that security manager allows it.

1 Comment

I get error, getThreads not defined for Thread. And I dont see this function in the documentation.
4

In the java console, hit Ctrl-Break. It will list all threads plus some information about the heap. This won't give you access to the objects of course. But it can be very helpful for debugging anyway.

Comments

3
 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 + " "); } } 

Comments

1

You can use getAllThreadIds that Returns all live thread IDs. Some threads included in the returned array may have been terminated when this method returns.

ManagementFactory.getThreadMXBean().getAllThreadIds() 

2 Comments

You should give more context around you answer to be useful to not only who asked the question, but also anyone else stumbling on the answer.
This gives the thread ids and not instances of the thread class, which is what this question is asking.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.