How to Find a Java Thread at Runtime
The art of finding threads at runtime involves two Java classes, Thread and ThreadGroup. In addition, you must remember to name your thread when you create it. Otherwise, if you do not name your thread, you are relying on the default naming mechanism for threads built into Java, and while you may be able to guess what the thread name should be, there is no guarantee it will be the same name across all runtime platforms and Java versions.
Instructions
-
-
1
Create the framework for a Java application class named "Find." Just provide an empty main() method as the starting point.
public class Find {
public static void main(String args[]) {
}
}
-
2
Create a Runnable object and Thread so that you have something to find. Name the thread "Sleeper" by providing a second argument to the Thread constructor, where the first argument is the Runnable reference. After creating the Thread, start it by calling its start() method. The following code starts off the now-empty main() method definition:
Runnable runner = new Runnable() {
public void run() {
try {
Thread.sleep(50000);
} catch (InterruptedException e) {
// ignore
}
}
};
Thread t = new Thread(runner, "Sleeper");
t.start();
-
-
3
Find the thread with the help of ThreadGroup. All threads belong to a ThreadGroup. These groups sit in a tree where all groups have a parent node (and children nodes), except for the root of the tree, which has no parent. Assuming the thread to find is not in the current thread's ThreadGroup, walk up to the top of the tree by looking at the group's parent. That way, when you go to find the "Sleeper" thread, you'll know that you've found it since all active threads will be children of the overlord parent thread.
Thread currentThread = Thread.currentThread();
ThreadGroup group = currentThread.getThreadGroup();
while (group.getParent() != null) {
group = group.getParent();
}
-
4
Use the enumerate() method of ThreadGroup to group all the children threads of this super parent. The method stores the active threads in an array.
int activeCount = group.activeCount();
Thread activeThreads[] = new Thread[activeCount+5];
int actualCount = group.enumerate(activeThreads);
-
5
Use the activeThreads array to help find the missing thread--here, the one marked "Sleeper." Once found, use the dumpStack() method to provide a stacktrace of the thread:
Thread found = null;
for (int i = 0; i < actualCount; i++) {
if ("Sleeper".equals(activeThreads[i].getName())) {
found = activeThreads[i];
break;
}
}
if (found != null) {
found.dumpStack();
}
-
6
As the closing line to your main() method, tell the system to exit out of memory:
System.exit(0);
-
7
Compile and run your program. While the line numbers in the stack trace could be slightly different based upon things like parentheses style, they all should provide the same general output.
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1206)
at Find.main(Find.java:31)
-
1
Tips & Warnings
The enumerate() method of ThreadGroup returns the number of entries put into the provided array. Do not depend on the length of the array to determine how many items are in the ThreadGroup.
When using the enumerate() method of ThreadGroup, leave enough space for growth in the provided array. The actual set of threads copied could change dynamically between when the size was queried to when the array gets filled.