首先,对于获得所有线程组和线程的分层输出的最简单解决方案,您只需要
getThreadRoot()
方法:
Functionality func = new Functionality();
func.getThreadRoot().list();
然而,它甚至会打印层次化的组,而不是只将线程作为子线程的组列表。为此,你必须
巢
你的循环,即。
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());
}
}
}
}
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;
}
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());
}
}
}
}
顺便说一句,自Java5以来,这可以很好地写成
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());
}
}
}
}
但请注意,这些
enumerate
不鼓励使用这种方法。它们不仅使用复杂,而且由于线程和组在处理过程中可能会发生变化,因此结果很容易出错。在一个时间点制作一个快照更简单、更可靠:
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());
}
}
当使用Java8特性时,这种逻辑变得更加简单:
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())
);
});