我可以弄清楚一个给定的线程是由这个线程还是这个线程的后代启动的?

时间:2017-12-28 19:50:31

标签: java multithreading logging

上下文:我想向根记录器添加日志Handler,以便从任务中收集所有日志记录输出。在任务执行期间,可能会创建其他线程。我也想要他们的日志输出。

其中一些线程是由库的方法创建的,例如Ant。

目前我的日志处理程序检查Thread方法中的当前publish,并存储该记录是否与原始任务线程相同。但我错过了任务线程产生的线程的日志消息。

只是开始/停止时间不起作用,因为多个任务同时运行,每个任务都有自己的潜在子线程。

1 个答案:

答案 0 :(得分:1)

每个线程实例都包含ThreadGroup。线程组形成一个树,其中除初始线程组之外的每个线程组都有父节点。使用此信息,我们可以应用ThreadGroup#parentOf(ThreadGroup)方法来检查当前线程是否是给定线程的父线程:

// 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;
}

如果使用调试器,某些IDE将显示每个正在运行的线程。以Eclipse's Debug View为例。程序中的每个线程都显示为树中的节点:

Debug View

如果你想更进一步做一些肮脏的工作,你可以使用反射来访问存储在给定线程组中的线程,但是我阻止你采取这些措施:

// 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...
 */

如果您的构建路径上碰巧有ThreadUtils.getAllThreadGroups(),您还可以使用Appache commons lang进行一些游戏。