Java tutorial
import java.awt.BorderLayout; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.lang.reflect.InvocationTargetException; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; public class ThreadViewer extends JPanel { private ThreadViewerTableModel tableModel = new ThreadViewerTableModel(); public ThreadViewer() { JTable table = new JTable(tableModel); table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); TableColumnModel colModel = table.getColumnModel(); int numColumns = colModel.getColumnCount(); for (int i = 0; i < numColumns - 1; i++) { TableColumn col = colModel.getColumn(i); col.sizeWidthToFit(); col.setPreferredWidth(col.getWidth() + 5); col.setMaxWidth(col.getWidth() + 5); } JScrollPane sp = new JScrollPane(table); setLayout(new BorderLayout()); add(sp, BorderLayout.CENTER); } public void dispose() { tableModel.stopRequest(); } protected void finalize() throws Throwable { dispose(); } public static void main(String[] args) { JFrame f = new JFrame(); ThreadViewer viewer = new ThreadViewer(); f.setContentPane(viewer); f.setSize(500, 300); f.setVisible(true); f.setDefaultCloseOperation(1); // Keep the main thread from exiting by blocking // on wait() for a notification that never comes. Object lock = new Object(); synchronized (lock) { try { lock.wait(); } catch (InterruptedException x) { } } } } class ThreadViewerTableModel extends AbstractTableModel { private Object dataLock; private int rowCount; private Object[][] cellData; private Object[][] pendingCellData; private final int columnCount; private final String[] columnName; private final Class[] columnClass; private Thread internalThread; private volatile boolean noStopRequested; public ThreadViewerTableModel() { rowCount = 0; cellData = new Object[0][0]; String[] names = { "Priority", "Alive", "Daemon", "Interrupted", "ThreadGroup", "Thread Name" }; columnName = names; Class[] classes = { Integer.class, Boolean.class, Boolean.class, Boolean.class, String.class, String.class }; columnClass = classes; columnCount = columnName.length; dataLock = new Object(); noStopRequested = true; Runnable r = new Runnable() { public void run() { try { runWork(); } catch (Exception x) { // in case ANY exception slips through x.printStackTrace(); } } }; internalThread = new Thread(r, "ThreadViewer"); internalThread.setPriority(Thread.MAX_PRIORITY - 2); internalThread.setDaemon(true); internalThread.start(); } private void runWork() { Runnable transferPending = new Runnable() { public void run() { transferPendingCellData(); fireTableDataChanged(); } }; while (noStopRequested) { try { createPendingCellData(); SwingUtilities.invokeAndWait(transferPending); Thread.sleep(5000); } catch (InvocationTargetException tx) { tx.printStackTrace(); stopRequest(); } catch (InterruptedException x) { Thread.currentThread().interrupt(); } } } public void stopRequest() { noStopRequested = false; internalThread.interrupt(); } public boolean isAlive() { return internalThread.isAlive(); } private void createPendingCellData() { Thread[] thread = findAllThreads(); Object[][] cell = new Object[thread.length][columnCount]; for (int i = 0; i < thread.length; i++) { Thread t = thread[i]; Object[] rowCell = cell[i]; rowCell[0] = new Integer(t.getPriority()); rowCell[1] = new Boolean(t.isAlive()); rowCell[2] = new Boolean(t.isDaemon()); rowCell[3] = new Boolean(t.isInterrupted()); rowCell[4] = t.getThreadGroup().getName(); rowCell[5] = t.getName(); } synchronized (dataLock) { pendingCellData = cell; } } private void transferPendingCellData() { synchronized (dataLock) { cellData = pendingCellData; rowCount = cellData.length; } } public int getRowCount() { return rowCount; } public Object getValueAt(int row, int col) { return cellData[row][col]; } public int getColumnCount() { return columnCount; } public Class getColumnClass(int columnIdx) { return columnClass[columnIdx]; } public String getColumnName(int columnIdx) { return columnName[columnIdx]; } public static Thread[] findAllThreads() { ThreadGroup group = Thread.currentThread().getThreadGroup(); ThreadGroup topGroup = group; while (group != null) { topGroup = group; group = group.getParent(); } int estimatedSize = topGroup.activeCount() * 2; Thread[] slackList = new Thread[estimatedSize]; int actualSize = topGroup.enumerate(slackList); Thread[] list = new Thread[actualSize]; System.arraycopy(slackList, 0, list, 0, actualSize); return list; } }