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;
}
}
|