Reto Höhener
Reto Höhener

Reputation: 5808

Can I figure out if a given thread has been started by this thread or a descendant of this thread?

Context: I want to add a log Handler to the root logger in order to collect all logging output from a task. During task execution, other threads might get created. I want their log output, too.

Some of those threads are created by methods of libraries, like Ant for example.

Currently my log handler checks the current Thread in the publish method, and stores the record if it is the same as the original task thread. But I miss the log messages of the threads spawned by the task thread.

Just going by start/stop time doesn't work either because multiple tasks are running concurrently, each with their own potential child-threads.

Upvotes: 1

Views: 69

Answers (1)

Cardinal System
Cardinal System

Reputation: 3420

Every thread instance has a ThreadGroup within it. The thread groups form a tree in which every thread group except the initial thread group has a parent. Using this information, we can apply the ThreadGroup#parentOf(ThreadGroup) method to check if the current thread is the parent of the given thread:

// potentialParent would probably just be Thread.currentThread();
public static boolean isChild(Thread potentialChild, Thread potentialParent) {
    try {
        return potentialParent.getThreadGroup().parentOf(potentialChild.getThreadGroup());
    }catch(NullPointerException e) {
        e.printStackTrace();            
    }
    return false;
}

Some IDEs will show every running thread if you use the debugger. Take Eclipse's Debug View for example. Each thread in your program appears as a node in the tree:

Debug View

If you want to take a step further and do some dirty work, you could use reflection to access the threads stored in given thread group, but I dissuade you from taking such measures:

// There is a thread array field in the ThreadGroup class.
Field f = ThreadGroup.class.getDeclaredField("threads");
// The 'threads' field has no access modifiers.
f.setAccessible(true);

Thread[] threads = (Thread[]) f.get(Thread.currentThread().getThreadGroup());
/*
 * Search 'threads' accordingly...
 */

You can also play around a bit with ThreadUtils.getAllThreadGroups() if you happen to have Appache commons lang on your build path.

Upvotes: 1

Related Questions