java dumpAllThreads参数解析

ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = tmx.dumpAllThreads(true, true);

通过上面的代码,我们可以将jvm进程的所有线程及堆栈dump下来。我们可以看到dump方法有两个参数: dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers)

这两个参数分别控制两种锁ThreadInfo .getLockedMonitors() 和ThreadInfo.getLockedSynchronizers()

a. Monitor 锁

就是我们传统使用的synchronized(Object obj),可以通过MonitorInfo[]得到具体的锁的数量和信息

  • 如果项目中使用synchronized,在dumpAllThreads第一个参数设置为true,就可以通过ThreadInfo.getLockedMonitors()获取线程持有的monitor
  • 相反如果一个参数设置为false,ThreadInfo.getLockedMonitors()这个就会返回为空

b. Locked ownable synchronizers 锁

常指的ReentrantLock 和 ReentrantReadWriteLock 锁
通过得到LockInfo[] 可以得到具体的类,锁的数量和信息

  • 如果项目中使用ReentrantLock,在dumpAllThreads第二个参数设置为true,就可以通过ThreadInfo.getLockedSynchronizers()获取线程持有的该类型锁。
  • 相反如果第二个参数设置为false,ThreadInfo.getLockedSynchronizers()这个就会返回为空

注意

ThreadMXBean.dumpAllThreads(true,true)因为要获取所有jvm线程的monitor和synchronizer信息,会挂起执行线程。对负载较大的服务器端程序,会引起latency飙升

下面我们通过一个示例看一下两个参数作用
public class RtTest {

    public static void main(String[] args) {
        final RtTest rt = new RtTest();
        for (int i = 0; i < 2; i++) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    rt.processLock();
                }
            });
            t.start();
        }

        final RtTest rt2 = new RtTest();
        for (int i = 0; i < 2; i++) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    rt2.processSync();
                }
            });
            t.start();
        }

        ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
        ThreadInfo[] threadInfos = tmx.dumpAllThreads(true, true);
        for (ThreadInfo threadInfo : threadInfos) {
            System.out.println(threadInfo);
        }

        System.out.println("hhhhhhhhhh");
        for (ThreadInfo threadInfo : threadInfos) {
            for (MonitorInfo lockedMonitor : threadInfo.getLockedMonitors()) {
                System.out.println(threadInfo.getThreadName()+":");
                System.out.println(lockedMonitor);
            }

        }

        System.out.println("oooooooo");
        for (ThreadInfo threadInfo : threadInfos) {
            for (LockInfo lockedSynchronizer : threadInfo.getLockedSynchronizers()) {
                System.out.println(threadInfo.getThreadName()+":");
                System.out.println(lockedSynchronizer);
            }

        }

    }

    public synchronized int processLock(){
        int l =0;
        for (int i = 0; i < 1000*1000*1000; i++) {
            l += i*i;
        }
        return l;
    }

    public synchronized void processSync(){
        ReentrantLock reentrantLock = new ReentrantLock();
        reentrantLock.lock();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        reentrantLock.unlock();
    }

结果输出如下:

"Thread-3" Id=14 BLOCKED on RtTest@2626b418 owned by "Thread-2" Id=13
    at RtTest.processSync(RtTest.java:69)
    -  blocked on RtTest@2626b418
    at RtTest$2.run(RtTest.java:28)
    at java.lang.Thread.run(Thread.java:745)


"Thread-2" Id=13 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at RtTest.processSync(RtTest.java:72)
    -  locked RtTest@2626b418
    at RtTest$2.run(RtTest.java:28)
    at java.lang.Thread.run(Thread.java:745)

    Number of locked synchronizers = 1
    - java.util.concurrent.locks.ReentrantLock$NonfairSync@5a07e868


"Thread-1" Id=12 BLOCKED on RtTest@76ed5528 owned by "Thread-0" Id=11
    at RtTest.processLock(RtTest.java:61)
    -  blocked on RtTest@76ed5528
    at RtTest$1.run(RtTest.java:17)
    at java.lang.Thread.run(Thread.java:745)


"Thread-0" Id=11 RUNNABLE
    at RtTest.processLock(RtTest.java:62)
    -  locked RtTest@76ed5528
    at RtTest$1.run(RtTest.java:17)
    at java.lang.Thread.run(Thread.java:745)


"Monitor Ctrl-Break" Id=5 RUNNABLE
    at java.net.NetworkInterface.init(Native Method)
    at java.net.NetworkInterface.(NetworkInterface.java:64)
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    -  locked java.net.SocksSocketImpl@2c7b84de
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    ...


"Signal Dispatcher" Id=4 RUNNABLE


"Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@3fee733d
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.ReferenceQueue$Lock@3fee733d
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)


"Reference Handler" Id=2 WAITING on java.lang.ref.Reference$Lock@5acf9800
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.Reference$Lock@5acf9800
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)


"main" Id=1 RUNNABLE
    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:446)
    at RtTest.main(RtTest.java:35)


hhhhhhhhhh
Thread-2:
RtTest@2626b418
Thread-0:
RtTest@76ed5528
Monitor Ctrl-Break:
java.net.SocksSocketImpl@2c7b84de
oooooooo
Thread-2:
java.util.concurrent.locks.ReentrantLock$NonfairSync@5a07e868

如果我们dump参数全部设置为false,即: ThreadInfo[] threadInfos = tmx.dumpAllThreads(false, false); 结果如下:

"Thread-3" Id=14 BLOCKED on RtTest@2626b418 owned by "Thread-2" Id=13
    at RtTest.processSync(RtTest.java:69)
    -  blocked on RtTest@2626b418
    at RtTest$2.run(RtTest.java:28)
    at java.lang.Thread.run(Thread.java:745)


"Thread-2" Id=13 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at RtTest.processSync(RtTest.java:72)
    at RtTest$2.run(RtTest.java:28)
    at java.lang.Thread.run(Thread.java:745)


"Thread-1" Id=12 BLOCKED on RtTest@5a07e868 owned by "Thread-0" Id=11
    at RtTest.processLock(RtTest.java:61)
    -  blocked on RtTest@5a07e868
    at RtTest$1.run(RtTest.java:17)
    at java.lang.Thread.run(Thread.java:745)


"Thread-0" Id=11 RUNNABLE
    at RtTest.processLock(RtTest.java:62)
    at RtTest$1.run(RtTest.java:17)
    at java.lang.Thread.run(Thread.java:745)


"Monitor Ctrl-Break" Id=5 RUNNABLE
    at java.lang.ClassLoader$NativeLibrary.find(Native Method)
    at java.lang.ClassLoader.findNative(ClassLoader.java:1960)
    at java.net.NetworkInterface.getAll(Native Method)
    at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343)
    at java.net.DefaultInterface.chooseDefaultInterface(DefaultInterface.java:67)
    at java.net.DefaultInterface.(DefaultInterface.java:46)
    at java.net.NetworkInterface.(NetworkInterface.java:65)
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    ...


"Signal Dispatcher" Id=4 RUNNABLE


"Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@76ed5528
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.ReferenceQueue$Lock@76ed5528
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)


"Reference Handler" Id=2 WAITING on java.lang.ref.Reference$Lock@2c7b84de
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.Reference$Lock@2c7b84de
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)


"main" Id=1 RUNNABLE
    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:446)
    at RtTest.main(RtTest.java:35)


hhhhhhhhhh
oooooooo

区别:

  • 获取不到Monitor和synchronizers锁信息了。
  • Thread-0、Thread-2的堆栈信息(此时两个线程正在运行,持有了该锁),不再显示锁信息。如下所示,缺少了lock
"Thread-0" Id=11 RUNNABLE
    at RtTest.processLock(RtTest.java:62)
    at RtTest$1.run(RtTest.java:17)
    at java.lang.Thread.run(Thread.java:745)

"Thread-0" Id=11 RUNNABLE
    at RtTest.processLock(RtTest.java:62)
    -  locked RtTest@76ed5528
    at RtTest$1.run(RtTest.java:17)
    at java.lang.Thread.run(Thread.java:745)

你可能感兴趣的:(java dumpAllThreads参数解析)