} // Return deadlocked threads or null public Long[][] getDeadlockedThreadIds() throws IOException { ProxyClient proxyClient = vmPanel.getProxyClient(); ThreadMXBean threadMBean = proxyClient.getThreadMXBean(); long[] ids = proxyClient.findDeadlockedThreads(); if (ids == null) { return null; } ThreadInfo[] infos = threadMBean.getThreadInfo(ids, Integer.MAX_VALUE); List<Long[]> dcycles = new ArrayList<Long[]>(); List<Long> cycle = new ArrayList<Long>(); // keep track of which thread is visited // one thread can only be in one cycle boolean[] visited = new boolean[ids.length]; int deadlockedThread = -1; // Index into arrays while (true) { if (deadlockedThread < 0) { if (cycle.size() > 0) { // a cycle found dcycles.add(cycle.toArray(new Long[0])); cycle = new ArrayList<Long>(); } // start a new cycle from a non-visited thread for (int j = 0; j < ids.length; j++) { if (!visited[j]) { deadlockedThread = j; visited[j] = true; break; } } if (deadlockedThread < 0) { // done break; } } cycle.add(ids[deadlockedThread]); long nextThreadId = infos[deadlockedThread].getLockOwnerId(); for (int j = 0; j < ids.length; j++) { ThreadInfo ti = infos[j]; if (ti.getThreadId() == nextThreadId) { if (visited[j]) { deadlockedThread = -1; } else { deadlockedThread = j; visited[j] = true; } break; } } } return dcycles.toArray(new Long[0][0]); } // ActionListener interface public void actionPerformed(ActionEvent evt) { String cmd = ((AbstractButton)evt.getSource()).getActionCommand(); if (cmd == "detectDeadlock") { messageLabel.setText(""); detectDeadlock(); } } // DocumentListener interface public void insertUpdate(DocumentEvent e) { doUpdate(); } public void removeUpdate(DocumentEvent e) { doUpdate(); } public void changedUpdate(DocumentEvent e) { doUpdate(); } private class ThreadJList extends JList { private JTextArea textArea; ThreadJList(DefaultListModel listModel, JTextArea textArea) { super(listModel); this.textArea = textArea; setBorder(thinEmptyBorder); addListSelectionListener(ThreadTab.this); setCellRenderer(new DefaultListCellRenderer() { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value != null) { String name = nameCache.get(value); if (name == null) { name = value.toString(); } setText(name); } return this; } }); } public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); d.width = Math.max(d.width, 100); return d; } } private class PromptingTextField extends JTextField implements FocusListener { private String prompt; boolean promptRemoved = false; Color fg; public PromptingTextField(String prompt, int columns) { super(prompt, columns); this.prompt = prompt; updateForeground(); addFocusListener(this); setAccessibleName(this, prompt); } @Override public void revalidate() { super.revalidate(); updateForeground(); } private void updateForeground() { this.fg = UIManager.getColor("TextField.foreground"); if (promptRemoved) { setForeground(fg); } else { setForeground(Color.gray); } } public String getText() { if (!promptRemoved) { return ""; } else { return super.getText(); } } public void focusGained(FocusEvent e) { if (!promptRemoved) { setText(""); setForeground(fg); promptRemoved = true; } } public void focusLost(FocusEvent e) { if (promptRemoved && getText().equals("")) { setText(prompt); setForeground(Color.gray); promptRemoved = false; } } } OverviewPanel[] getOverviewPanels() { if (overviewPanel == null) { overviewPanel = new ThreadOverviewPanel(); } return new OverviewPanel[] { overviewPanel }; } private static class ThreadOverviewPanel extends OverviewPanel { ThreadOverviewPanel() { super(getText("Threads"), threadCountKey, threadCountName, null); } private void updateThreadsInfo(long tlCount, long tpCount, long ttCount, long timeStamp) { getPlotter().addValues(timeStamp, tlCount); getInfoLabel().setText(getText(infoLabelFormat, tlCount, tpCount, ttCount)); } }}Lines 501–702 of 702. Previous lines
} // Return deadlocked threads or null public Long[][] getDeadlockedThreadIds() throws IOException { ProxyClient proxyClient = vmPanel.getProxyClient(); ThreadMXBean threadMBean = proxyClient.getThreadMXBean(); long[] ids = proxyClient.findDeadlockedThreads(); if (ids == null) { return null; } ThreadInfo[] infos = threadMBean.getThreadInfo(ids, Integer.MAX_VALUE); List<Long[]> dcycles = new ArrayList<Long[]>(); List<Long> cycle = new ArrayList<Long>(); // keep track of which thread is visited // one thread can only be in one cycle boolean[] visited = new boolean[ids.length]; int deadlockedThread = -1; // Index into arrays while (true) { if (deadlockedThread < 0) { if (cycle.size() > 0) { // a cycle found dcycles.add(cycle.toArray(new Long[0])); cycle = new ArrayList<Long>(); } // start a new cycle from a non-visited thread for (int j = 0; j < ids.length; j++) { if (!visited[j]) { deadlockedThread = j; visited[j] = true; break; } } if (deadlockedThread < 0) { // done break; } } cycle.add(ids[deadlockedThread]); long nextThreadId = infos[deadlockedThread].getLockOwnerId(); for (int j = 0; j < ids.length; j++) { ThreadInfo ti = infos[j]; if (ti.getThreadId() == nextThreadId) { if (visited[j]) { deadlockedThread = -1; } else { deadlockedThread = j; visited[j] = true; } break; } } } return dcycles.toArray(new Long[0][0]); } // ActionListener interface public void actionPerformed(ActionEvent evt) { String cmd = ((AbstractButton)evt.getSource()).getActionCommand(); if (cmd == "detectDeadlock") { messageLabel.setText(""); detectDeadlock(); } } // DocumentListener interface public void insertUpdate(DocumentEvent e) { doUpdate(); } public void removeUpdate(DocumentEvent e) { doUpdate(); } public void changedUpdate(DocumentEvent e) { doUpdate(); } private class ThreadJList extends JList { private JTextArea textArea; ThreadJList(DefaultListModel listModel, JTextArea textArea) { super(listModel); this.textArea = textArea; setBorder(thinEmptyBorder); addListSelectionListener(ThreadTab.this); setCellRenderer(new DefaultListCellRenderer() { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value != null) { String name = nameCache.get(value); if (name == null) { name = value.toString(); } setText(name); } return this; } }); } public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); d.width = Math.max(d.width, 100); return d; } } private class PromptingTextField extends JTextField implements FocusListener { private String prompt; boolean promptRemoved = false; Color fg; public PromptingTextField(String prompt, int columns) { super(prompt, columns); this.prompt = prompt; updateForeground(); addFocusListener(this); setAccessibleName(this, prompt); } @Override public void revalidate() { super.revalidate(); updateForeground(); } private void updateForeground() { this.fg = UIManager.getColor("TextField.foreground"); if (promptRemoved) { setForeground(fg); } else { setForeground(Color.gray); } } public String getText() { if (!promptRemoved) { return ""; } else { return super.getText(); } } public void focusGained(FocusEvent e) { if (!promptRemoved) { setText(""); setForeground(fg); promptRemoved = true; } } public void focusLost(FocusEvent e) { if (promptRemoved && getText().equals("")) { setText(prompt); setForeground(Color.gray); promptRemoved = false; } } } OverviewPanel[] getOverviewPanels() { if (overviewPanel == null) { overviewPanel = new ThreadOverviewPanel(); } return new OverviewPanel[] { overviewPanel }; } private static class ThreadOverviewPanel extends OverviewPanel { ThreadOverviewPanel() { super(getText("Threads"), threadCountKey, threadCountName, null); } private void updateThreadsInfo(long tlCount, long tpCount, long ttCount, long timeStamp) { getPlotter().addValues(timeStamp, tlCount); getInfoLabel().setText(getText(infoLabelFormat, tlCount, tpCount, ttCount)); } } }