271

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.

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
Kryten
  • 3,843
  • 5
  • 37
  • 42

13 Answers13

382

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).

user1050755
  • 11,218
  • 4
  • 45
  • 56
thejoshwolfe
  • 5,328
  • 3
  • 29
  • 21
  • 24
    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 Sep 03 '11 at 02:56
  • 34
    @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](http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize) according to Donald Knuth. – thejoshwolfe Sep 03 '11 at 05:08
  • 22
    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). – Eddie Sep 08 '11 at 15:55
  • 4
    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. – Franz D. Mar 05 '15 at 17:48
  • @FranzD., thanks for doing the research. This strategy may not be suitable for all applications, but don't forget about other factors when comparing code. For example, this code that is arguably easier to read and write than a more performant solution. Also, don't forget about the performance penalties built into the Java runtime iteself, such as garbage collection. It may be informative to measure the performance impact in your actual application. – thejoshwolfe Mar 06 '15 at 23:38
  • 5
    @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. – Franz D. Mar 07 '15 at 00:54
  • Getting a stack trace on HotSpot requires all the threads to reach a safepoint. See "VM Operations and Safepoints": http://openjdk.java.net/groups/hotspot/docs/RuntimeOverview.html – David Phillips Dec 16 '15 at 17:14
  • 1
    Can someone comment as to whether or not the stacktrace method returns threads that are currently RUNNING, or does it also include threads that are in a TERMINATED state? – Michael Sims Aug 29 '18 at 17:57
  • No working in my Java 8 standalone web application. I did not dig deep why, but it misses a whole bunch of running threads. – Vlad at MockMotor Feb 24 '19 at 02:09
  • I do not agree that the Thread.getAllStackTraces is the right way to go. It asked for set of thread class. While the answer does give that value, it also intermittently get and then throw away stack traces. And it calls the dumpThreads JNI method which has a huge performance penalty, which it does not really need to, since you only need to call the getThreads JNI method in the thread class. This answer is fine for a pre production or test environment but its a bad idea in production and should be actively avoided. – Arunav Sanyal Nov 03 '21 at 05:32
  • Please be respectful of other opinions and the people who criticize you. Calling other solutions "shocked that this strategy is so popular" and [Argument from authority](https://en.wikipedia.org/wiki/Argument_from_authority) for anyone who points out your downside is not a good way to discuss. – Jason Lee Dec 05 '21 at 02:24
  • A bit more perf data: 111 threads in a JVM running a Clojure REPL with a multi-threaded app takes 1.14-1.36 ms (95% CI) to enumerate with this method on a 2019 MacBook Pro with AdoptOpenJDK 8. – Nathan Tuggy Dec 27 '21 at 15:55
  • (For comparison, the main alternative method executes in 9.57-10.6 µs in the same REPL that still has 111 threads, so close to two orders of magnitude faster.) – Nathan Tuggy Dec 27 '21 at 16:20
87

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.

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
  • 23
    I'm shocked that this strategy is so popular on the internet. [My strategy](http://stackoverflow.com/questions/1323408/get-a-list-of-all-threads-currently-running-in-java/3018672#3018672) is way simpler (1 line of code) and works just as well with the added bonus of avoiding race conditions. – thejoshwolfe Aug 15 '11 at 05:49
  • 13
    @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. – Frerich Raabe Oct 23 '12 at 21:16
  • 4
    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. – jmiserez Jul 31 '14 at 22:55
  • 9
    @thejoshwolfe I suppose this solution is much less expensive. – Haozhun Aug 22 '14 at 23:40
  • 23
    +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. – Franz D. Mar 05 '15 at 17:44
  • Beware of that in android 5.0 or 5.1,`Thread.getAllStackTraces()` may cause GC. – legendmohe Jul 03 '18 at 07:13
  • One could argue that the authors of `org.apache.commons.lang3.ThreadUtils` opting for this approach over `Thread.getAllStackTraces()` for its `getSystemThreadGroup()` and various `findThreads()` methods, is a rather prominent endorsement of this answer being best practice. – Andreas Klein Nov 15 '19 at 06:03
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.

bspar
  • 40
  • 1
  • 5
cletus
  • 616,129
  • 168
  • 910
  • 942
  • 5
    kill -3? At least on my linux, that's "terminal quit". Kills, does not list. – Michael H. Aug 24 '09 at 16:45
  • 6
    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. – Dan Hardiker Apr 06 '14 at 10:00
  • 1
    [getting a list of threads](http://nadeausoftware.com/articles/2008/04/java_tip_how_list_and_find_threads_and_thread_groups#Gettingalistofallthreads) can’t be reached: nadeausoftware.com refused to connect. – DSlomer64 Jun 17 '20 at 17:55
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.

Dan Dyer
  • 53,737
  • 19
  • 129
  • 165
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.

pjp
  • 17,039
  • 6
  • 33
  • 58
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.

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
hasskell
  • 441
  • 3
  • 7
12

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());
}
palacsint
  • 28,416
  • 10
  • 82
  • 109
gerardw
  • 5,822
  • 46
  • 39
10

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.

Amir Fo
  • 5,163
  • 1
  • 43
  • 51
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
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
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.

Jarek Przygódzki
  • 4,284
  • 2
  • 31
  • 41
  • I get error, getThreads not defined for Thread. And I dont see this function in the documentation. –  Sep 26 '19 at 18:26
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.

raoulsson
  • 14,978
  • 11
  • 44
  • 68
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 + "  ");
        }
    }
ZZ Coder
  • 74,484
  • 29
  • 137
  • 169
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()
Amir Fo
  • 5,163
  • 1
  • 43
  • 51
Martin Kersten
  • 5,127
  • 8
  • 46
  • 77
  • 6
    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. – Prateek Feb 15 '18 at 01:10
  • This gives the thread ids and not instances of the thread class, which is what this question is asking. – Arunav Sanyal Nov 03 '21 at 05:34