代码之家  ›  专栏  ›  技术社区  ›  user8359804

显示当前在JVM中运行的所有线程组和线程

  •  2
  • user8359804  · 技术社区  · 6 年前

    因此,我的任务是显示所有线程组以及当前在JVM中运行的属于这些组的所有线程。

    输出时,应先显示螺纹组,然后在下面显示该组中的所有踏板。这是为所有线程组完成的。目前,我的代码将只显示每个线程组,然后显示每个线程,但我不确定如何达到我所描述的输出。

    这是我当前的代码:

    public  ThreadGroup getThreadRoot() {
        ThreadGroup rootGroup = Thread.currentThread( ).getThreadGroup( );
        ThreadGroup parentGroup;
        while ( ( parentGroup = rootGroup.getParent() ) != null ) {
            rootGroup = parentGroup;
        }
        return rootGroup;
    }
    
    public  ThreadGroup[] getAllThreadGroups(){
    
    
        ThreadGroup root= getThreadRoot();
        int estimate = root.activeGroupCount();
        ThreadGroup [] threads = new ThreadGroup[estimate];
        while ( root.enumerate( threads, true ) == threads.length ) {
            threads = new ThreadGroup[ threads.length * 2 ];
        }
    
    
        ThreadGroup[] allGroups = new ThreadGroup[threads.length+1];
        allGroups[0] = root;
        System.arraycopy( threads, 0, allGroups, 1, estimate );
        return allGroups;
    
    }
    public Thread[] getAllThreads(){
    
         ThreadGroup root= getThreadRoot();
         int estimate = root.activeGroupCount();
         Thread [] allThreads = new Thread[estimate];
         while ( root.enumerate( allThreads, true ) == allThreads.length ) {
             allThreads = new Thread[ allThreads.length * 2 ];
         }
    
    
         return allThreads;
    
    }
    

    主要方法:

    public static void main(String[] args)   {
    
        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 i=0; i<t.length; i++) {
            if(t[i] != null){
            System.out.println("Name: " + t[i].getName() + ", id: " + t[i].getId() 
                    + ", State: " + t[i].getState() + ", Is daemon? " + t[i].isDaemon());
            }
    }
    }
    
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   user502187 user502187    5 年前

    获取所有线程的另一种方法是使用ThreadMXBean:

    ThreadMXBean thbean = ManagementFactory.getThreadMXBean();
    final long[] ids = thbean.getAllThreadIds();
    

    从那里你可以获得各种信息,另请参阅:

    https://github.com/liguobing/ToolCode/blob/master/ThreadUtilities.java

        2
  •  0
  •   Holger    6 年前

    首先,对于获得所有线程组和线程的分层输出的最简单解决方案,您只需要 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())
        );
    });