获取 Java VM 中当前运行的所有线程
程序运行图:
下面的静态方法可以用数组返回 Java VM 中当前运行的所有线程
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);
// copy into a list that is the exact size
Thread[] list = new Thread[actualSize];
System.arraycopy(slackList, 0, list, 0, actualSize);
return list;
}
程序 ThreadViewer.java 以图形方式显示 Java VM 中当前运行的所有线程,它每隔 2 秒自动刷新一次,以保持获得最新信息。程序 ThreadViewer.java 源代码:
- packagethread;
- importjava.awt.*;
- importjava.awt.event.*;
- importjavax.swing.*;
- importjavax.swing.table.*;
- publicclassThreadViewerextendsJPanel{
- privateThreadViewerTableModeltableModel;
- publicThreadViewer(){
- tableModel=newThreadViewerTableModel();
- JTabletable=newJTable(tableModel);
- table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
- TableColumnModelcolModel=table.getColumnModel();
- intnumColumns=colModel.getColumnCount();
- //manuallysizeallbutthelastcolumn
- for(inti=0;i<numColumns-1;i++){
- TableColumncol=colModel.getColumn(i);
- col.sizeWidthToFit();
- col.setPreferredWidth(col.getWidth()+5);
- col.setMaxWidth(col.getWidth()+5);
- }
- JScrollPanesp=newJScrollPane(table);
- setLayout(newBorderLayout());
- add(sp,BorderLayout.CENTER);
- }
- publicvoiddispose(){
- tableModel.stopRequest();
- }
- protectedvoidfinalize()throwsThrowable{
- dispose();
- }
- publicstaticJFramecreateFramedInstance(){
- finalThreadViewerviewer=newThreadViewer();
- finalJFramef=newJFrame("ThreadViewer");
- f.addWindowListener(newWindowAdapter(){
- publicvoidwindowClosing(WindowEvente){
- f.setVisible(false);
- f.dispose();
- viewer.dispose();
- }
- });
- f.setContentPane(viewer);
- f.setSize(500,300);
- f.setVisible(true);
- returnf;
- }
- publicstaticvoidmain(String[]args){
- JFramef=ThreadViewer.createFramedInstance();
- //Forthisexample,exittheVMwhentheviewer
- //frameisclosed.
- f.addWindowListener(newWindowAdapter(){
- publicvoidwindowClosing(WindowEvente){
- System.exit(0);
- }
- });
- //Keepthemainthreadfromexitingbyblocking
- //onwait()foranotificationthatnevercomes.
- Objectlock=newObject();
- synchronized(lock){
- try{
- lock.wait();
- }catch(InterruptedExceptionx){
- }
- }
- }
- }
程序 ThreadViewerTableModel.java 源代码:
- packagethread;
- importjava.awt.*;
- importjava.lang.reflect.*;
- importjavax.swing.*;
- importjavax.swing.table.*;
- publicclassThreadViewerTableModelextendsAbstractTableModel{
- privateObjectdataLock;
- privateintrowCount;
- privateObject[][]cellData;
- privateObject[][]pendingCellData;
- //thecolumninformationremainsconstant
- privatefinalintcolumnCount;
- privatefinalString[]columnName;
- privatefinalClass[]columnClass;
- //self-runningobjectcontrolvariables
- privateThreadinternalThread;
- privatevolatilebooleannoStopRequested;
- publicThreadViewerTableModel(){
- rowCount=0;
- cellData=newObject[0][0];
- //JTableusesthisinformationforthecolumnheaders
- String[]names={
- "Priority","Alive",
- "Daemon","Interrupted",
- "ThreadGroup","ThreadName"};
- columnName=names;
- //JTableusesthisinformationforcellrendering
- Class[]classes={
- Integer.class,Boolean.class,
- Boolean.class,Boolean.class,
- String.class,String.class};
- columnClass=classes;
- columnCount=columnName.length;
- //usedtocontrolconcurrentaccess
- dataLock=newObject();
- noStopRequested=true;
- Runnabler=newRunnable(){
- publicvoidrun(){
- try{
- runWork();
- }catch(Exceptionx){
- //incaseANYexceptionslipsthrough
- x.printStackTrace();
- }
- }
- };
- internalThread=newThread(r,"ThreadViewer");
- internalThread.setPriority(Thread.MAX_PRIORITY-2);
- internalThread.setDaemon(true);
- internalThread.start();
- }
- privatevoidrunWork(){
- //Therun()methodoftransferPendingiscalledby
- //theeventhandlingthreadforsafeconcurrency.
- RunnabletransferPending=newRunnable(){
- publicvoidrun(){
- transferPendingCellData();
- //MethodofAbstractTableModelthat
- //causesthetabletobeupdated.
- fireTableDataChanged();
- }
- };
- while(noStopRequested){
- try{
- createPendingCellData();
- SwingUtilities.invokeAndWait(transferPending);
- Thread.sleep(2000);
- }catch(InvocationTargetExceptiontx){
- tx.printStackTrace();
- stopRequest();
- }catch(InterruptedExceptionx){
- Thread.currentThread().interrupt();
- }
- }
- }
- publicvoidstopRequest(){
- noStopRequested=false;
- internalThread.interrupt();
- }
- publicbooleanisAlive(){
- returninternalThread.isAlive();
- }
- privatevoidcreatePendingCellData(){
- //thismethodiscalledbytheinternalthread
- Thread[]thread=findAllThreads();
- Object[][]cell=newObject[thread.length][columnCount];
- for(inti=0;i<thread.length;i++){
- Threadt=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;
- }
- }
- privatevoidtransferPendingCellData(){
- //thismethodiscalledbytheeventthread
- synchronized(dataLock){
- cellData=pendingCellData;
- rowCount=cellData.length;
- }
- }
- publicintgetRowCount(){
- //thismethodiscalledbytheeventthread
- returnrowCount;
- }
- publicObjectgetValueAt(introw,intcol){
- //thismethodiscalledbytheeventthread
- returncellData[row][col];
- }
- publicintgetColumnCount(){
- returncolumnCount;
- }
- publicClassgetColumnClass(intcolumnIdx){
- returncolumnClass[columnIdx];
- }
- publicStringgetColumnName(intcolumnIdx){
- returncolumnName[columnIdx];
- }
- publicstaticThread[]findAllThreads(){
- ThreadGroupgroup=
- Thread.currentThread().getThreadGroup();
- ThreadGrouptopGroup=group;
- //traversetheThreadGrouptreetothetop
- while(group!=null){
- topGroup=group;
- group=group.getParent();
- }
- //Createadestinationarraythatisabout
- //twiceasbigasneededtobeveryconfident
- //thatnoneareclipped.
- intestimatedSize=topGroup.activeCount()*2;
- Thread[]slackList=newThread[estimatedSize];
- //Loadthethreadreferencesintotheoversized
- //array.Theactualnumberofthreadsloaded
- //isreturned.
- intactualSize=topGroup.enumerate(slackList);
- //copyintoalistthatistheexactsize
- Thread[]list=newThread[actualSize];
- System.arraycopy(slackList,0,list,0,actualSize);
- returnlist;
- }
- }