Get a List of All Threads Currently Running in Java

Get a list of all threads currently running in Java

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

Displaying all thread groups and threads currently running in JVM

First of all, for the simplest solution to get a hierarchical output of all thread groups and threads, you only need your getThreadRoot() method:

Functionality func = new Functionality();
func.getThreadRoot().list();

however, it will print even the groups hierarchical rather than a list of groups with only the threads as children. For this, you have to nest your loops, i.e.

CreateDummyGroups create = new CreateDummyGroups();
Functionality func = new Functionality();
ThreadGroup[] tg = func.getAllThreadGroups();
Thread[] t = func.getAllThreads();
for(int i=0; i<tg.length; i++) {
if(tg[i] != null) {
System.out.println("Name: " + tg[i].getName());
for(int j=0; j<t.length; j++) {
if(t[j] != null && t[j].getThreadGroup() == tg[i]) {
System.out.println(" Name: " + t[j].getName() + ", id: " + t[j].getId()
+ ", State: " + t[j].getState() + ", Is daemon? " + t[j].isDaemon());
}
}
}
}

This uses a reference comparison in the inner loop, to only show the threads of the current group. More efficient would be to only get threads of the current group in the first place, i.e. add a method to your Functionality:

public Thread[] getThreadsOf(ThreadGroup group) {
int estimate = group.activeCount();
Thread[] groupThreads = new Thread[estimate];
while(group.enumerate( groupThreads, false ) == groupThreads.length) {
groupThreads = new Thread[ groupThreads.length * 2 ];
}
return groupThreads;
}

and change the caller to

CreateDummyGroups create = new CreateDummyGroups();
Functionality func = new Functionality();
ThreadGroup[] tg = func.getAllThreadGroups();
for(int i=0; i<tg.length; i++) {
if(tg[i] != null) {
System.out.println("Name: " + tg[i].getName());
Thread[] t = func.getThreadsOf(tg[i]);
for(int j=0; j<t.length; j++) {
if(t[j] != null) {
System.out.println(" Name: " + t[j].getName() + ", id: " + t[j].getId()
+ ", State: " + t[j].getState() + ", Is daemon? " + t[j].isDaemon());
}
}
}
}

By the way, since Java 5, this can be nicely written as

CreateDummyGroups create = new CreateDummyGroups();
Functionality func = new Functionality();
for(ThreadGroup tg: func.getAllThreadGroups()) {
if(tg != null) {
System.out.println("Name: " + tg.getName());
for(Thread t: func.getThreadsOf(tg)) {
if(t != null) {
System.out.println(" Name: " + t.getName() + ", id: " + t.getId()
+ ", State: " + t.getState() + ", Is daemon? " + t.isDaemon());
}
}
}
}

But note that these old enumerate methods are highly discouraged. They are not only complicated to use, the result is error prone due to the fact that the threads and groups may change while you are processing them. It’s much simpler and more reliable to work on a single snapshot made at one point of time:

CreateDummyGroups create = new CreateDummyGroups();
Map<ThreadGroup, List<Thread>> map = new LinkedHashMap<>();
for(Thread thread: Thread.getAllStackTraces().keySet()) {
List<Thread> list = map.get(thread.getThreadGroup());
if(list == null) {
list = new ArrayList<>();
map.put(thread.getThreadGroup(), list);
}
list.add(thread);
}


for(Map.Entry<ThreadGroup,List<Thread>> groupEntry: map.entrySet()) {
System.out.println("Name: " + groupEntry.getKey().getName());
for(Thread thread: groupEntry.getValue()) {
System.out.println(" Name: " + thread.getName() + ", id: " + thread.getId()
+ ", State: " + thread.getState() + ", Is daemon? " + thread.isDaemon());
}
}

This logic becomes even simpler when using Java 8 features:

CreateDummyGroups create = new CreateDummyGroups();
Map<ThreadGroup, List<Thread>> map = Thread.getAllStackTraces().keySet()
.stream().collect(Collectors.groupingBy(Thread::getThreadGroup));


map.forEach((group,threadList) -> {
System.out.println("Name: " + group.getName());
threadList.forEach(thread ->
System.out.println(" Name: " + thread.getName() + ", id: " + thread.getId()
+ ", State: " + thread.getState() + ", Is daemon? " + thread.isDaemon())
);
});

List of currently running threads

As per documentation of ThreadGroup, the method

public int enumerate(Thread[] list,
boolean recurse)

will recursively enumerate the subgroups. However, it only returns as many threads that can be filled in list argument. So, the code tries to allocate more size to list if it observes that you have received exactly length elements in the list with the assumption that there were more threads to enumerate but array size was not sufficient.

So, when loop terminates, even if you have length elements in the list, last few elements will be null and you will have to ignore them while determining thread count

How to find and stop all currently running threads?

This is a dangerous idea. The Javadoc for Thread.stop() explains:

This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.

Fundamentally, threads need to be built and designed to safely terminate, it is not possible to safely kill arbitrary threads. A fairly standard pattern is implemented like so:

public abstract class StoppableRunnable implements Runnable {
private volatile boolean stopWork;
private boolean done;

public final void run() {
setup();
while(!stopWork && !done) {
doUnitOfWork();
}
cleanup();
}

/**
* Safely instructs this thread to stop working,
* letting it finish it's current unit of work,
* then doing any necessary cleanup and terminating
* the thread. Notice that this does not guarentee
* the thread will stop, as doUnitOfWork() could
* block if not properly implemented.
*/
public void stop() {
stopWork = true;
}

protected void done() {
done = true;
}

protected void setup() { }
protected void cleanup() { }

/**
* Does as small a unit of work as can be defined
* for this thread. Once there is no more work to
* be done, done() should be called.
*/
protected abstract void doUnitOfWork();
}

You implied you aren't the author of these threads, which suggest they may not be safely stoppable. In such a case, you can call Thread.interrupt() to instruct the thread to stop what it's doing (instead of the pattern described above, you could use Thread.interrupt() to similar effect) however similarly, if the thread's designer hasn't written it to handle interrupts, this may not do anything or cause inconsistent states or other errors.

Ultimately, Thread.stop() is what you want if you just want to "[Force] the thread to stop executing" and can't modify the thread's implementation; however like using kill in Unix, this is a dangerous proposition, and you should essentially consider your JVM to be in an unstable and irreparable state after terminating a thread in this way, and attempt to exit the program as quickly as possible thereafter.


Regarding your suggestion of interrupting then stopping:

There's still a lot of problems here, in particular, interrupting does not guarantee the thread will interrupt immediately (it works similarly, though less explicitly, to my StoppableRunnable above) and instead sets a flag that the thread should interrupt when possible. This means you could call Thread.interrupt(), the thread could start it's proper interrupt-handling behavior, then midway through that, your call to Thread.stop() fires, violently killing the thread and potentially breaking your JVM. Calls to Thread.interrupt() provide no guarantee as to when or how the thread will respond to that interrupt, which is why I prefer the explicit behavior in StoppableRunnable. Needless to say, if you're ever going to call Thread.stop() there's little to be gained by calling Thread.interrupt() first. I don't recommend it, but you might as well just call Thread.stop() in the first place.

Additionally, recognize that the code running your loop is itself in a thread - meaning your loop could very well kill itself first, leaving all other threads running.

How to get the currently running custom Threads variables

Couple of easy ways to handle this.
Full working code on online java ide

What are you trying to achieve?
The run() method always runs in the thread were the instance is ThreadEngine.

So you could simply use getProcessid() in the run() method to access the process id.

At any other place, if you want to access the current thread, you could simply use
Thread.currentThread() that returns the current thread.

If you are looking for any thread instead of just current thread, then you should make sure if it is of the current instance type using the instanceof keyword.

I have attached the working code in codiva java online compiler ide.

Count only currently active threads

tl;dr

Compare the state of the thread:

thread.getState().equals( Thread.State.RUNNABLE )

Here is an example making a stream from your list of Thread objects.

threads
.stream()
.filter(
thread -> thread.getState().equals( Thread.State.RUNNABLE )
)
.count() // Or collect them: `.toList()`

Or count all active threads:

Thread.activeCount()

Details

I have no experience in this, but looking the Javadoc for Thread, I see getState. That method returns a Thread.State enum object. Documentation says:

A thread can be in one of the following states, as quoted from the doc:

  • NEW
    A thread that has not yet started is in this state.
  • RUNNABLE
    A thread executing in the Java virtual machine is in this state.
  • BLOCKED
    A thread that is blocked waiting for a monitor lock is in this state.
  • WAITING
    A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
  • TIMED_WAITING
    A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
  • TERMINATED
    A thread that has exited is in this state.

So loop your Thread objects, fetch their State, and see if it is RUNNABLE.

for ( Thread thread : list) {
if ( thread.getState().equals( Thread.State.RUNNABLE ) ) {

}
}

But if you just want a count of all active threads, call Thread.activeCount().

How to check the number of currently running threads in Java?

This will give you the total number of threads in your VM :

int nbThreads =  Thread.getAllStackTraces().keySet().size();

Now, if you want all threads currently executing, you can do that :

int nbRunning = 0;
for (Thread t : Thread.getAllStackTraces().keySet()) {
if (t.getState()==Thread.State.RUNNABLE) nbRunning++;
}

The possible states are enumerated here: Thread.State javadoc

If you want to see running threads not programmaticaly but with a Windows tool, you could use Process Explorer.



Related Topics



Leave a reply



Submit