ThreadViewerTableModel.java
上传用户:songled
上传日期:2022-07-14
资源大小:94k
文件大小:5k
源码类别:

进程与线程

开发平台:

Java

  1. import java.awt.*;
  2. import java.lang.reflect.*;
  3. import javax.swing.*;
  4. import javax.swing.table.*;
  5. public class ThreadViewerTableModel extends AbstractTableModel {
  6. private Object dataLock; 
  7. private int rowCount;
  8. private Object[][] cellData;
  9. private Object[][] pendingCellData;
  10. // the column information remains constant
  11. private final int columnCount;
  12. private final String[] columnName;
  13. private final Class[] columnClass;
  14. // self-running object control variables
  15. private Thread internalThread;
  16. private volatile boolean noStopRequested;
  17. public ThreadViewerTableModel() {
  18. rowCount = 0;
  19. cellData = new Object[0][0];
  20. // JTable uses this information for the column headers
  21. String[] names = { 
  22. "Priority", "Alive", 
  23. "Daemon", "Interrupted", 
  24. "ThreadGroup", "Thread Name" };
  25. columnName = names;
  26. // JTable uses this information for cell rendering
  27. Class[] classes = { 
  28. Integer.class, Boolean.class, 
  29. Boolean.class, Boolean.class, 
  30. String.class, String.class };
  31. columnClass = classes;
  32. columnCount = columnName.length;
  33. // used to control concurrent access
  34. dataLock = new Object(); 
  35. noStopRequested = true;
  36. Runnable r = new Runnable() {
  37. public void run() {
  38. try {
  39. runWork();
  40. } catch ( Exception x ) {
  41. // in case ANY exception slips through
  42. x.printStackTrace(); 
  43. }
  44. }
  45. };
  46. internalThread = new Thread(r, "ThreadViewer");
  47. internalThread.setPriority(Thread.MAX_PRIORITY - 2);
  48. internalThread.setDaemon(true);
  49. internalThread.start();
  50. }
  51. private void runWork() {
  52. // The run() method of transferPending is called by 
  53. // the event handling thread for safe concurrency.
  54. Runnable transferPending = new Runnable() {
  55. public void run() {
  56. transferPendingCellData();
  57. // Method of AbstractTableModel that 
  58. // causes the table to be updated.
  59. fireTableDataChanged(); 
  60. }
  61. };
  62. while ( noStopRequested ) {
  63. try {
  64. createPendingCellData();
  65. SwingUtilities.invokeAndWait(transferPending);
  66. Thread.sleep(5000);
  67. } catch ( InvocationTargetException tx ) {
  68. tx.printStackTrace();
  69. stopRequest();
  70. } catch ( InterruptedException x ) {
  71. Thread.currentThread().interrupt(); 
  72. }
  73. }
  74. }
  75. public void stopRequest() {
  76. noStopRequested = false;
  77. internalThread.interrupt();
  78. }
  79. public boolean isAlive() {
  80. return internalThread.isAlive();
  81. }
  82. private void createPendingCellData() {
  83. // this method is called by the internal thread
  84. Thread[] thread = findAllThreads();
  85. Object[][] cell = new Object[thread.length][columnCount];
  86. for ( int i = 0; i < thread.length; i++ ) {
  87. Thread t = thread[i];
  88. Object[] rowCell = cell[i];
  89. rowCell[0] = new Integer(t.getPriority());
  90. rowCell[1] = new Boolean(t.isAlive());
  91. rowCell[2] = new Boolean(t.isDaemon());
  92. rowCell[3] = new Boolean(t.isInterrupted());
  93. rowCell[4] = t.getThreadGroup().getName();
  94. rowCell[5] = t.getName();
  95. }
  96. synchronized ( dataLock ) {
  97. pendingCellData = cell;
  98. }
  99. }
  100. private void transferPendingCellData() {
  101. // this method is called by the event thread
  102. synchronized ( dataLock ) {
  103. cellData = pendingCellData;
  104. rowCount = cellData.length;
  105. }
  106. }
  107. public int getRowCount() {
  108. // this method is called by the event thread
  109. return rowCount;
  110. }
  111. public Object getValueAt(int row, int col) {
  112. // this method is called by the event thread
  113. return cellData[row][col];
  114. }
  115. public int getColumnCount() {
  116. return columnCount;
  117. }
  118. public Class getColumnClass(int columnIdx) {
  119. return columnClass[columnIdx];
  120. }
  121. public String getColumnName(int columnIdx) {
  122. return columnName[columnIdx];
  123. }
  124. public static Thread[] findAllThreads() {
  125. ThreadGroup group = 
  126. Thread.currentThread().getThreadGroup();
  127. ThreadGroup topGroup = group;
  128. // traverse the ThreadGroup tree to the top
  129. while ( group != null ) {
  130. topGroup = group;
  131. group = group.getParent();
  132. }
  133. // Create a destination array that is about
  134. // twice as big as needed to be very confident
  135. // that none are clipped.
  136. int estimatedSize = topGroup.activeCount() * 2;
  137. Thread[] slackList = new Thread[estimatedSize];
  138. // Load the thread references into the oversized
  139. // array. The actual number of threads loaded 
  140. // is returned.
  141. int actualSize = topGroup.enumerate(slackList);
  142. // copy into a list that is the exact size
  143. Thread[] list = new Thread[actualSize];
  144. System.arraycopy(slackList, 0, list, 0, actualSize);
  145. return list;
  146. }
  147. }