ThreadzServlet extends BaseStatusServlet implements Capturable { @VisibleForTesting static Map<Stack, List<String>> deduplicateThreadStacks( Map<Thread, StackTraceElement[]> allStacks) { Map<Stack, List<String>> stacks = new HashMap<>(); for (Map.Entry<Thread, StackTraceElement[]> entry : allStacks.entrySet()) { Thread thread = entry.getKey(); if (thread != Thread.currentThread()) { Stack stack = new Stack(entry.getValue(), thread.getState()); List<String> threads = stacks.get(stack); if (threads == null) { threads = new ArrayList<>(); stacks.put(stack, threads); } threads.add(thread.toString()); } } return stacks; } ThreadzServlet(); @Override void doGet(HttpServletRequest request, HttpServletResponse response); @Override String pageName(); @Override void captureData(PrintWriter writer);  }
@Test public void testDeduping() throws Exception { Map<Thread, StackTraceElement[]> stacks = ImmutableMap.of( new Thread("Thread1"), new StackTraceElement[] {new StackTraceElement("Class", "Method1", "File", 11)}, new Thread("Thread2"), new StackTraceElement[] {new StackTraceElement("Class", "Method1", "File", 11)}, new Thread("Thread3"), new StackTraceElement[] {new StackTraceElement("Class", "Method2", "File", 17)}); Map<Stack, List<String>> deduped = ThreadzServlet.deduplicateThreadStacks(stacks); assertEquals(2, deduped.size()); assertThat( deduped, Matchers.hasEntry( new Stack( new StackTraceElement[] {new StackTraceElement("Class", "Method1", "File", 11)}, Thread.State.NEW), Arrays.asList("Thread[Thread1,5,main]", "Thread[Thread2,5,main]"))); assertThat( deduped, Matchers.hasEntry( new Stack( new StackTraceElement[] {new StackTraceElement("Class", "Method2", "File", 17)}, Thread.State.NEW), Arrays.asList("Thread[Thread3,5,main]"))); }