packagecom.isoftstone.pcis.isc.job.king.panel;import java.awt.*;import java.lang.reflect.*;import javax.swing.*;import javax.swing.table.*;public class ThreadViewerTableModel extendsAbstractTableModel {privateObject dataLock;private introwCount;privateObject[][] cellData;privateObject[][] pendingCellData;//the column information remains constant
private final intcolumnCount;private finalString[] columnName;private finalClass[] columnClass;//self-running object control variables
privateThread internalThread;private volatile booleannoStopRequested;publicThreadViewerTableModel() {
rowCount= 0;
cellData= new Object[0][0];//JTable uses this information for the column headers
String[] names ={"Priority", "Alive","Daemon", "Interrupted","ThreadGroup", "Thread Name"};
columnName=names;//JTable uses this information for cell rendering
Class[] classes ={
Integer.class, Boolean.class,
Boolean.class, Boolean.class,
String.class, String.class};
columnClass=classes;
columnCount=columnName.length;//used to control concurrent access
dataLock = newObject();
noStopRequested= true;
Runnable r= newRunnable() {public voidrun() {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 voidrunWork() {//The run() method of transferPending is called by//the event handling thread for safe concurrency.
Runnable transferPending = newRunnable() {public voidrun() {
transferPendingCellData();//Method of AbstractTableModel that//causes the table to be updated.
fireTableDataChanged();
}
};while( noStopRequested ) {try{
createPendingCellData();
SwingUtilities.invokeAndWait(transferPending);
Thread.sleep(2000);
}catch( InvocationTargetException tx ) {
tx.printStackTrace();
stopRequest();
}catch( InterruptedException x ) {
Thread.currentThread().interrupt();
}
}
}public voidstopRequest() {
noStopRequested= false;
internalThread.interrupt();
}public booleanisAlive() {returninternalThread.isAlive();
}private voidcreatePendingCellData() {//this method is called by the internal thread
Thread[] thread =findAllThreads();
Object[][] cell= newObject[thread.length][columnCount];for ( int i = 0; i < thread.length; i++) {
Thread t=thread[i];
Object[] rowCell=cell[i];
rowCell[0] = newInteger(t.getPriority());
rowCell[1] = newBoolean(t.isAlive());
rowCell[2] = newBoolean(t.isDaemon());
rowCell[3] = newBoolean(t.isInterrupted());
rowCell[4] =t.getThreadGroup().getName();
rowCell[5] =t.getName();
}synchronized( dataLock ) {
pendingCellData=cell;
}
}private voidtransferPendingCellData() {//this method is called by the event thread
synchronized( dataLock ) {
cellData=pendingCellData;
rowCount=cellData.length;
}
}public intgetRowCount() {//this method is called by the event thread
returnrowCount;
}public Object getValueAt(int row, intcol) {//this method is called by the event thread
returncellData[row][col];
}public intgetColumnCount() {returncolumnCount;
}public Class getColumnClass(intcolumnIdx) {returncolumnClass[columnIdx];
}public String getColumnName(intcolumnIdx) {returncolumnName[columnIdx];
}public staticThread[] findAllThreads() {
ThreadGroup group=Thread.currentThread().getThreadGroup();
ThreadGroup topGroup=group;//traverse the ThreadGroup tree to the top
while ( group != null) {
topGroup=group;
group=group.getParent();
}//Create a destination array that is about//twice as big as needed to be very confident//that none are clipped.
int estimatedSize = topGroup.activeCount() * 2;
Thread[] slackList= newThread[estimatedSize];//Load the thread references into the oversized//array. The actual number of threads loaded//is returned.
int actualSize =topGroup.enumerate(slackList);//copy into a list that is the exact size
Thread[] list = newThread[actualSize];
System.arraycopy(slackList,0, list, 0, actualSize);returnlist;
}
}