Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ThreadMXBean.dumpAllThreads() maxDepth

I'm trying to write some Thread Management utility, and reading up on ThreadMXBean.

http://download.oracle.com/javase/6/docs/api/java/lang/management/ThreadMXBean.html#dumpAllThreads(boolean, boolean)

According to the doc, getThreadInfo(long[] ids, int maxDepth) "does not obtain the locked monitors and locked synchronizers of the threads", however, those methods that allow you to specify true to obtain lock/monitor information do not seem to enable you to specify maxDepth.

Is there anything I can do to specify both whether or not to obtain monitor/lock info as well as stack depth?

Thanks in advance!

like image 617
RAY Avatar asked Dec 27 '22 16:12

RAY


1 Answers

You can copy the toString() from ThreadInfo, but remove the stack depth limitation to give you this :

    public String dump(ThreadInfo info) {
        
        StringBuilder sb = new StringBuilder("\"" + info.getThreadName() + "\""
                + " Id=" + info.getThreadId() + " " + info.getThreadState());
        if (info.getLockName() != null) {
            sb.append(" on " + info.getLockName());
        }
        if (info.getLockOwnerName() != null) {
            sb.append(" owned by \"" + info.getLockOwnerName() + "\" Id="
                    + info.getLockOwnerId());
        }
        if (info.isSuspended()) {
            sb.append(" (suspended)");
        }
        if (info.isInNative()) {
            sb.append(" (in native)");
        }
        sb.append('\n');
        int i = 0;
        for (; i < info.getStackTrace().length; i++) {
            StackTraceElement ste = info.getStackTrace()[i];
            sb.append("\tat " + ste.toString());
            sb.append('\n');
            if (i == 0 && info.getLockInfo() != null) {
                Thread.State ts = info.getThreadState();
                switch (ts) {
                case BLOCKED:
                    sb.append("\t-  blocked on " + info.getLockInfo());
                    sb.append('\n');
                    break;
                case WAITING:
                    sb.append("\t-  waiting on " + info.getLockInfo());
                    sb.append('\n');
                    break;
                case TIMED_WAITING:
                    sb.append("\t-  waiting on " + info.getLockInfo());
                    sb.append('\n');
                    break;
                default:
                }
            }

            for (MonitorInfo mi : info.getLockedMonitors()) {
                if (mi.getLockedStackDepth() == i) {
                    sb.append("\t-  locked " + mi);
                    sb.append('\n');
                }
            }
        }
        if (i < info.getStackTrace().length) {
            sb.append("\t...");
            sb.append('\n');
        }

        LockInfo[] locks = info.getLockedSynchronizers();
        if (locks.length > 0) {
            sb.append("\n\tNumber of locked synchronizers = " + locks.length);
            sb.append('\n');
            for (LockInfo li : locks) {
                sb.append("\t- " + li);
                sb.append('\n');
            }
        }
        sb.append('\n');
        return sb.toString();
    }

Then call this method for each ThreadInfo returned from ThreadMxBean.dumpAllThreads()

Here is a gist with a utility class that has this method along with some sonarlint cleanup: https://gist.github.com/nddipiazza/13edf47fae104c34dd0331704bcf04e9

like image 181
sbridges Avatar answered Dec 30 '22 06:12

sbridges