Java多线程编程核心技术(第3版)
上QQ阅读APP看书,第一时间看更新

1.9 方法Map<Thread, StackTraceElement[]> getAllStackTraces()

Map<Thread, StackTraceElement[]> getAllStackTraces()方法的作用是返回所有活动线程的堆栈信息的一个映射。Map的key是线程对象,而Map的value是一个StackTraceElement数组,该数组表示相应Thread的堆栈信息。在调用该方法的同时,线程可能也在执行。每个线程的堆栈信息仅代表线程当时状态的一个快照。

创建测试用的代码如下:


package test8;

import java.util.Iterator;
import java.util.Map;

public class Test1 {

    public void a() {
        b();
    }

    public void b() {
        c();
    }

    public void c() {
        d();
    }

    public void d() {
        e();
    }

    public void e() {
        Map<Thread, StackTraceElement[]> map = Thread.currentThread().getAll
            StackTraces();
        if (map != null && map.size() != 0) {
            Iterator keyIterator = map.keySet().iterator();
            while (keyIterator.hasNext()) {
                Thread eachThread = (Thread) keyIterator.next();
                StackTraceElement[] array = map.get(eachThread);
                System.out.println("------每个线程的基本信息");
                System.out.println("  线程名称:" + eachThread.getName());
                System.out.println(" StackTraceElement[].length=" + array.length);
                System.out.println("  线程的状态:" + eachThread.getState());
                if (array.length != 0) {
                    System.out.println("  打印StackTraceElement[]数组具体信息:");
                    for (int i = 0; i < array.length; i++) {
                        StackTraceElement eachElement = array[i];
                        System.out.println("    " + eachElement.getClassName() + 
                            " " + eachElement.getMethodName() + " "
                                + eachElement.getFileName() + " " + eachElement.
                                    getLineNumber());
                    }
                } else {
                    System.out.println("  没有StackTraceElement[]信息,因为线程" + 
                        eachThread.getName()
                            + "中的StackTraceElement[].length==0");
                }
                System.out.println();
                System.out.println();
            }
        }
    }

    public static void main(String[] args) {
        Test1 test1 = new Test1();
        test1.a();
    }
}

程序运行结果如下所示。


------每个线程的基本信息
    线程名称:Signal Dispatcher
StackTraceElement[].length=0
    线程的状态:RUNNABLE
    没有StackTraceElement[]信息,因为线程Signal Dispatcher中的StackTraceElement[].
        length==0

------每个线程的基本信息
    线程名称:main
StackTraceElement[].length=8
    线程的状态:RUNNABLE
    打印StackTraceElement[]数组具体信息:
        java.lang.Thread dumpThreads Thread.java -2
        java.lang.Thread getAllStackTraces Thread.java 1610
        test8.Test1 e Test1.java 25
        test8.Test1 d Test1.java 21
        test8.Test1 c Test1.java 17
        test8.Test1 b Test1.java 13
        test8.Test1 a Test1.java 9
        test8.Test1 main Test1.java 54

------每个线程的基本信息
    线程名称:Attach Listener
StackTraceElement[].length=0
    线程的状态:RUNNABLE
    没有StackTraceElement[]信息,因为线程Attach Listener中的StackTraceElement[].
        length==0

------每个线程的基本信息
    线程名称:Finalizer
StackTraceElement[].length=4
    线程的状态:WAITING
    打印StackTraceElement[]数组具体信息:
        java.lang.Object wait Object.java -2
        java.lang.ref.ReferenceQueue remove ReferenceQueue.java 143
        java.lang.ref.ReferenceQueue remove ReferenceQueue.java 164
        java.lang.ref.Finalizer$FinalizerThread run Finalizer.java 209


------每个线程的基本信息
    线程名称:Reference Handler
StackTraceElement[].length=4
    线程的状态:WAITING
    打印StackTraceElement[]数组具体信息:
        java.lang.Object wait Object.java -2
        java.lang.Object wait Object.java 502
        java.lang.ref.Reference tryHandlePending Reference.java 191
        java.lang.ref.Reference$ReferenceHandler run Reference.java 153

注意

getLineNumber()方法返回负数,比如-2代表没有具体的行号信息,大多数是因为调用了native方法才会返回-2。