2011-07-26 7 views
2

Я пытаюсь написать некоторую утилиту управления потоками и читать на ThreadMXBean.ThreadMXBean.dumpAllThreads() maxDepth

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

Согласно документу, getThreadInfo (длинный [] Идентификаторы, внутр maxDepth) «не получает заблокированные мониторы и заблокированные синхронизаторы из нитей», однако, те методы, которые позволяют вам указать верный получить информацию о блокировке/мониторе, похоже, не позволяют указать maxDepth.

Есть ли что-нибудь, что я могу сделать, чтобы указать, нужно ли получать информацию о мониторе/блокировке, а также глубину стека?

Заранее благодарен!

ответ

4

Вы можете скопировать ToString() из ThreadInfo, но снять ограничение глубины стека, чтобы дать вам это:

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(); 
    } 

Затем вызовите этот метод для каждого ThreadInfo вернулся из ThreadMxBean.dumpAllThreads()

+0

Спасибо , Хороший указатель. Хотелось бы посмотреть, есть ли способ ограничить глубину возвращаемого ThreadInfos. На мой взгляд, это халатность в дизайне API. Если в методе есть два полностью независимых параметра, то * должен * быть перегрузкой метода, в котором пользователь может указать оба варианта. – RAY

+0

Важно указать максимальную глубину при получении ThreadInfo. http://stackoverflow.com/questions/4315753/requesting-a-stack-trace-for-a-java-threadinfo – Deep

Смежные вопросы