001 /*
002 * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.lang.management;
027
028 import javax.management.openmbean.CompositeData;
029 import sun.management.ThreadInfoCompositeData;
030 import static java.lang.Thread.State.*;
031
032 /**
033 * Thread information. <tt>ThreadInfo</tt> contains the information
034 * about a thread including:
035 * <h4>General thread information</h4>
036 * <ul>
037 * <li>Thread ID.</li>
038 * <li>Name of the thread.</li>
039 * </ul>
040 *
041 * <h4>Execution information</h4>
042 * <ul>
043 * <li>Thread state.</li>
044 * <li>The object upon which the thread is blocked due to:
045 * <ul>
046 * <li>waiting to enter a synchronization block/method, or</li>
047 * <li>waiting to be notified in a {@link Object#wait Object.wait} method,
048 * or</li>
049 * <li>parking due to a {@link java.util.concurrent.locks.LockSupport#park
050 * LockSupport.park} call.</li>
051 * </ul>
052 * </li>
053 * <li>The ID of the thread that owns the object
054 * that the thread is blocked.</li>
055 * <li>Stack trace of the thread.</li>
056 * <li>List of object monitors locked by the thread.</li>
057 * <li>List of <a href="LockInfo.html#OwnableSynchronizer">
058 * ownable synchronizers</a> locked by the thread.</li>
059 * </ul>
060 *
061 * <h4><a name="SyncStats">Synchronization Statistics</a></h4>
062 * <ul>
063 * <li>The number of times that the thread has blocked for
064 * synchronization or waited for notification.</li>
065 * <li>The accumulated elapsed time that the thread has blocked
066 * for synchronization or waited for notification
067 * since {@link ThreadMXBean#setThreadContentionMonitoringEnabled
068 * thread contention monitoring}
069 * was enabled. Some Java virtual machine implementation
070 * may not support this. The
071 * {@link ThreadMXBean#isThreadContentionMonitoringSupported()}
072 * method can be used to determine if a Java virtual machine
073 * supports this.</li>
074 * </ul>
075 *
076 * <p>This thread information class is designed for use in monitoring of
077 * the system, not for synchronization control.
078 *
079 * <h4>MXBean Mapping</h4>
080 * <tt>ThreadInfo</tt> is mapped to a {@link CompositeData CompositeData}
081 * with attributes as specified in
082 * the {@link #from from} method.
083 *
084 * @see ThreadMXBean#getThreadInfo
085 * @see ThreadMXBean#dumpAllThreads
086 *
087 * @author Mandy Chung
088 * @version 1.31, 05/05/07
089 * @since 1.5
090 */
091
092 public class ThreadInfo {
093 private String threadName;
094 private long threadId;
095 private long blockedTime;
096 private long blockedCount;
097 private long waitedTime;
098 private long waitedCount;
099 private LockInfo lock;
100 private String lockName;
101 private long lockOwnerId;
102 private String lockOwnerName;
103 private boolean inNative;
104 private boolean suspended;
105 private Thread.State threadState;
106 private StackTraceElement[] stackTrace;
107 private MonitorInfo[] lockedMonitors;
108 private LockInfo[] lockedSynchronizers;
109
110 private static MonitorInfo[] EMPTY_MONITORS = new MonitorInfo[0];
111 private static LockInfo[] EMPTY_SYNCS = new LockInfo[0];
112
113 /**
114 * Constructor of ThreadInfo created by the JVM
115 *
116 * @param t Thread
117 * @param state Thread state
118 * @param lockObj Object on which the thread is blocked
119 * @param lockOwner the thread holding the lock
120 * @param blockedCount Number of times blocked to enter a lock
121 * @param blockedTime Approx time blocked to enter a lock
122 * @param waitedCount Number of times waited on a lock
123 * @param waitedTime Approx time waited on a lock
124 * @param stackTrace Thread stack trace
125 */
126 private ThreadInfo(Thread t, int state, Object lockObj,
127 Thread lockOwner, long blockedCount, long blockedTime,
128 long waitedCount, long waitedTime,
129 StackTraceElement[] stackTrace) {
130 initialize(t, state, lockObj, lockOwner, blockedCount,
131 blockedTime, waitedCount, waitedTime, stackTrace,
132 EMPTY_MONITORS, EMPTY_SYNCS);
133 }
134
135 /**
136 * Constructor of ThreadInfo created by the JVM
137 * for {@link ThreadMXBean#getThreadInfo(long[],boolean,boolean)}
138 * and {@link ThreadMXBean#dumpAllThreads}
139 *
140 * @param t Thread
141 * @param state Thread state
142 * @param lockObj Object on which the thread is blocked
143 * @param lockOwner the thread holding the lock
144 * @param blockedCount Number of times blocked to enter a lock
145 * @param blockedTime Approx time blocked to enter a lock
146 * @param waitedCount Number of times waited on a lock
147 * @param waitedTime Approx time waited on a lock
148 * @param stackTrace Thread stack trace
149 * @param lockedMonitors List of locked monitors
150 * @param lockedSynchronizers List of locked synchronizers
151 */
152 private ThreadInfo(Thread t, int state, Object lockObj,
153 Thread lockOwner, long blockedCount, long blockedTime,
154 long waitedCount, long waitedTime,
155 StackTraceElement[] stackTrace, Object[] monitors,
156 int[] stackDepths, Object[] synchronizers) {
157 int numMonitors = (monitors == null ? 0 : monitors.length);
158 MonitorInfo[] lockedMonitors;
159 if (numMonitors == 0) {
160 lockedMonitors = EMPTY_MONITORS;
161 } else {
162 lockedMonitors = new MonitorInfo[numMonitors];
163 for (int i = 0; i < numMonitors; i++) {
164 Object lock = monitors[i];
165 String className = lock.getClass().getName();
166 int identityHashCode = System.identityHashCode(lock);
167 int depth = stackDepths[i];
168 StackTraceElement ste = (depth >= 0 ? stackTrace[depth]
169 : null);
170 lockedMonitors[i] = new MonitorInfo(className,
171 identityHashCode, depth, ste);
172 }
173 }
174
175 int numSyncs = (synchronizers == null ? 0
176 : synchronizers.length);
177 LockInfo[] lockedSynchronizers;
178 if (numSyncs == 0) {
179 lockedSynchronizers = EMPTY_SYNCS;
180 } else {
181 lockedSynchronizers = new LockInfo[numSyncs];
182 for (int i = 0; i < numSyncs; i++) {
183 Object lock = synchronizers[i];
184 String className = lock.getClass().getName();
185 int identityHashCode = System.identityHashCode(lock);
186 lockedSynchronizers[i] = new LockInfo(className,
187 identityHashCode);
188 }
189 }
190
191 initialize(t, state, lockObj, lockOwner, blockedCount,
192 blockedTime, waitedCount, waitedTime, stackTrace,
193 lockedMonitors, lockedSynchronizers);
194 }
195
196 /**
197 * Initialize ThreadInfo object
198 *
199 * @param t Thread
200 * @param state Thread state
201 * @param lockObj Object on which the thread is blocked
202 * @param lockOwner the thread holding the lock
203 * @param blockedCount Number of times blocked to enter a lock
204 * @param blockedTime Approx time blocked to enter a lock
205 * @param waitedCount Number of times waited on a lock
206 * @param waitedTime Approx time waited on a lock
207 * @param stackTrace Thread stack trace
208 * @param lockedMonitors List of locked monitors
209 * @param lockedSynchronizers List of locked synchronizers
210 */
211 private void initialize(Thread t, int state, Object lockObj,
212 Thread lockOwner, long blockedCount, long blockedTime,
213 long waitedCount, long waitedTime,
214 StackTraceElement[] stackTrace,
215 MonitorInfo[] lockedMonitors, LockInfo[] lockedSynchronizers) {
216 this .threadId = t.getId();
217 this .threadName = t.getName();
218 this .threadState = sun.management.ManagementFactory
219 .toThreadState(state);
220 this .suspended = sun.management.ManagementFactory
221 .isThreadSuspended(state);
222 this .inNative = sun.management.ManagementFactory
223 .isThreadRunningNative(state);
224 this .blockedCount = blockedCount;
225 this .blockedTime = blockedTime;
226 this .waitedCount = waitedCount;
227 this .waitedTime = waitedTime;
228
229 if (lockObj == null) {
230 this .lock = null;
231 this .lockName = null;
232 } else {
233 this .lock = new LockInfo(lockObj);
234 this .lockName = lock.getClassName() + '@'
235 + Integer.toHexString(lock.getIdentityHashCode());
236 }
237 if (lockOwner == null) {
238 this .lockOwnerId = -1;
239 this .lockOwnerName = null;
240 } else {
241 this .lockOwnerId = lockOwner.getId();
242 this .lockOwnerName = lockOwner.getName();
243 }
244 if (stackTrace == null) {
245 this .stackTrace = NO_STACK_TRACE;
246 } else {
247 this .stackTrace = stackTrace;
248 }
249 this .lockedMonitors = lockedMonitors;
250 this .lockedSynchronizers = lockedSynchronizers;
251 }
252
253 /*
254 * Constructs a <tt>ThreadInfo</tt> object from a
255 * {@link CompositeData CompositeData}.
256 */
257 private ThreadInfo(CompositeData cd) {
258 ThreadInfoCompositeData ticd = ThreadInfoCompositeData
259 .getInstance(cd);
260
261 threadId = ticd.threadId();
262 threadName = ticd.threadName();
263 blockedTime = ticd.blockedTime();
264 blockedCount = ticd.blockedCount();
265 waitedTime = ticd.waitedTime();
266 waitedCount = ticd.waitedCount();
267 lockName = ticd.lockName();
268 lockOwnerId = ticd.lockOwnerId();
269 lockOwnerName = ticd.lockOwnerName();
270 threadState = ticd.threadState();
271 suspended = ticd.suspended();
272 inNative = ticd.inNative();
273 stackTrace = ticd.stackTrace();
274
275 // 6.0 attributes
276 if (ticd.isCurrentVersion()) {
277 lock = ticd.lockInfo();
278 lockedMonitors = ticd.lockedMonitors();
279 lockedSynchronizers = ticd.lockedSynchronizers();
280 } else {
281 // lockInfo is a new attribute added in 1.6 ThreadInfo
282 // If cd is a 5.0 version, construct the LockInfo object
283 // from the lockName value.
284 if (lockName != null) {
285 String result[] = lockName.split("@");
286 if (result.length == 2) {
287 int identityHashCode = Integer.parseInt(result[1],
288 16);
289 lock = new LockInfo(result[0], identityHashCode);
290 } else {
291 assert result.length == 2;
292 lock = null;
293 }
294 } else {
295 lock = null;
296 }
297 lockedMonitors = EMPTY_MONITORS;
298 lockedSynchronizers = EMPTY_SYNCS;
299 }
300 }
301
302 /**
303 * Returns the ID of the thread associated with this <tt>ThreadInfo</tt>.
304 *
305 * @return the ID of the associated thread.
306 */
307 public long getThreadId() {
308 return threadId;
309 }
310
311 /**
312 * Returns the name of the thread associated with this <tt>ThreadInfo</tt>.
313 *
314 * @return the name of the associated thread.
315 */
316 public String getThreadName() {
317 return threadName;
318 }
319
320 /**
321 * Returns the state of the thread associated with this <tt>ThreadInfo</tt>.
322 *
323 * @return <tt>Thread.State</tt> of the associated thread.
324 */
325 public Thread.State getThreadState() {
326 return threadState;
327 }
328
329 /**
330 * Returns the approximate accumulated elapsed time (in milliseconds)
331 * that the thread associated with this <tt>ThreadInfo</tt>
332 * has blocked to enter or reenter a monitor
333 * since thread contention monitoring is enabled.
334 * I.e. the total accumulated time the thread has been in the
335 * {@link java.lang.Thread.State#BLOCKED BLOCKED} state since thread
336 * contention monitoring was last enabled.
337 * This method returns <tt>-1</tt> if thread contention monitoring
338 * is disabled.
339 *
340 * <p>The Java virtual machine may measure the time with a high
341 * resolution timer. This statistic is reset when
342 * the thread contention monitoring is reenabled.
343 *
344 * @return the approximate accumulated elapsed time in milliseconds
345 * that a thread entered the <tt>BLOCKED</tt> state;
346 * <tt>-1</tt> if thread contention monitoring is disabled.
347 *
348 * @throws java.lang.UnsupportedOperationException if the Java
349 * virtual machine does not support this operation.
350 *
351 * @see ThreadMXBean#isThreadContentionMonitoringSupported
352 * @see ThreadMXBean#setThreadContentionMonitoringEnabled
353 */
354 public long getBlockedTime() {
355 return blockedTime;
356 }
357
358 /**
359 * Returns the total number of times that
360 * the thread associated with this <tt>ThreadInfo</tt>
361 * blocked to enter or reenter a monitor.
362 * I.e. the number of times a thread has been in the
363 * {@link java.lang.Thread.State#BLOCKED BLOCKED} state.
364 *
365 * @return the total number of times that the thread
366 * entered the <tt>BLOCKED</tt> state.
367 */
368 public long getBlockedCount() {
369 return blockedCount;
370 }
371
372 /**
373 * Returns the approximate accumulated elapsed time (in milliseconds)
374 * that the thread associated with this <tt>ThreadInfo</tt>
375 * has waited for notification
376 * since thread contention monitoring is enabled.
377 * I.e. the total accumulated time the thread has been in the
378 * {@link java.lang.Thread.State#WAITING WAITING}
379 * or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state
380 * since thread contention monitoring is enabled.
381 * This method returns <tt>-1</tt> if thread contention monitoring
382 * is disabled.
383 *
384 * <p>The Java virtual machine may measure the time with a high
385 * resolution timer. This statistic is reset when
386 * the thread contention monitoring is reenabled.
387 *
388 * @return the approximate accumulated elapsed time in milliseconds
389 * that a thread has been in the <tt>WAITING</tt> or
390 * <tt>TIMED_WAITING</tt> state;
391 * <tt>-1</tt> if thread contention monitoring is disabled.
392 *
393 * @throws java.lang.UnsupportedOperationException if the Java
394 * virtual machine does not support this operation.
395 *
396 * @see ThreadMXBean#isThreadContentionMonitoringSupported
397 * @see ThreadMXBean#setThreadContentionMonitoringEnabled
398 */
399 public long getWaitedTime() {
400 return waitedTime;
401 }
402
403 /**
404 * Returns the total number of times that
405 * the thread associated with this <tt>ThreadInfo</tt>
406 * waited for notification.
407 * I.e. the number of times that a thread has been
408 * in the {@link java.lang.Thread.State#WAITING WAITING}
409 * or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state.
410 *
411 * @return the total number of times that the thread
412 * was in the <tt>WAITING</tt> or <tt>TIMED_WAITING</tt> state.
413 */
414 public long getWaitedCount() {
415 return waitedCount;
416 }
417
418 /**
419 * Returns the <tt>LockInfo</tt> of an object for which
420 * the thread associated with this <tt>ThreadInfo</tt>
421 * is blocked waiting.
422 * A thread can be blocked waiting for one of the following:
423 * <ul>
424 * <li>an object monitor to be acquired for entering or reentering
425 * a synchronization block/method.
426 * <br>The thread is in the {@link java.lang.Thread.State#BLOCKED BLOCKED}
427 * state waiting to enter the <tt>synchronized</tt> statement
428 * or method.
429 * <p></li>
430 * <li>an object monitor to be notified by another thread.
431 * <br>The thread is in the {@link java.lang.Thread.State#WAITING WAITING}
432 * or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state
433 * due to a call to the {@link Object#wait Object.wait} method.
434 * <p></li>
435 * <li>a synchronization object responsible for the thread parking.
436 * <br>The thread is in the {@link java.lang.Thread.State#WAITING WAITING}
437 * or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state
438 * due to a call to the
439 * {@link java.util.concurrent.locks.LockSupport#park(Object)
440 * LockSupport.park} method. The synchronization object
441 * is the object returned from
442 * {@link java.util.concurrent.locks.LockSupport#getBlocker
443 * LockSupport.getBlocker} method. Typically it is an
444 * <a href="LockInfo.html#OwnableSynchronizer"> ownable synchronizer</a>
445 * or a {@link java.util.concurrent.locks.Condition Condition}.</li>
446 * </ul>
447 *
448 * <p>This method returns <tt>null</tt> if the thread is not in any of
449 * the above conditions.
450 *
451 * @return <tt>LockInfo</tt> of an object for which the thread
452 * is blocked waiting if any; <tt>null</tt> otherwise.
453 * @since 1.6
454 */
455 public LockInfo getLockInfo() {
456 return lock;
457 }
458
459 /**
460 * Returns the {@link LockInfo#toString string representation}
461 * of an object for which the thread associated with this
462 * <tt>ThreadInfo</tt> is blocked waiting.
463 * This method is equivalent to calling:
464 * <blockquote>
465 * <pre>
466 * getLockInfo().toString()
467 * </pre></blockquote>
468 *
469 * <p>This method will return <tt>null</tt> if this thread is not blocked
470 * waiting for any object or if the object is not owned by any thread.
471 *
472 * @return the string representation of the object on which
473 * the thread is blocked if any;
474 * <tt>null</tt> otherwise.
475 *
476 * @see #getLockInfo
477 */
478 public String getLockName() {
479 return lockName;
480 }
481
482 /**
483 * Returns the ID of the thread which owns the object
484 * for which the thread associated with this <tt>ThreadInfo</tt>
485 * is blocked waiting.
486 * This method will return <tt>-1</tt> if this thread is not blocked
487 * waiting for any object or if the object is not owned by any thread.
488 *
489 * @return the thread ID of the owner thread of the object
490 * this thread is blocked on;
491 * <tt>-1</tt> if this thread is not blocked
492 * or if the object lis not owned by any thread.
493 *
494 * @see #getLockInfo
495 */
496 public long getLockOwnerId() {
497 return lockOwnerId;
498 }
499
500 /**
501 * Returns the name of the thread which owns the object
502 * for which the thread associated with this <tt>ThreadInfo</tt>
503 * is blocked waiting.
504 * This method will return <tt>null</tt> if this thread is not blocked
505 * waiting for any object or if the object is not owned by any thread.
506 *
507 * @return the name of the thread that owns the object
508 * this thread is blocked on;
509 * <tt>null</tt> if this thread is not blocked
510 * or if the object is not owned by any thread.
511 *
512 * @see #getLockInfo
513 */
514 public String getLockOwnerName() {
515 return lockOwnerName;
516 }
517
518 /**
519 * Returns the stack trace of the thread
520 * associated with this <tt>ThreadInfo</tt>.
521 * If no stack trace was requested for this thread info, this method
522 * will return a zero-length array.
523 * If the returned array is of non-zero length then the first element of
524 * the array represents the top of the stack, which is the most recent
525 * method invocation in the sequence. The last element of the array
526 * represents the bottom of the stack, which is the least recent method
527 * invocation in the sequence.
528 *
529 * <p>Some Java virtual machines may, under some circumstances, omit one
530 * or more stack frames from the stack trace. In the extreme case,
531 * a virtual machine that has no stack trace information concerning
532 * the thread associated with this <tt>ThreadInfo</tt>
533 * is permitted to return a zero-length array from this method.
534 *
535 * @return an array of <tt>StackTraceElement</tt> objects of the thread.
536 */
537 public StackTraceElement[] getStackTrace() {
538 return stackTrace;
539 }
540
541 /**
542 * Tests if the thread associated with this <tt>ThreadInfo</tt>
543 * is suspended. This method returns <tt>true</tt> if
544 * {@link Thread#suspend} has been called.
545 *
546 * @return <tt>true</tt> if the thread is suspended;
547 * <tt>false</tt> otherwise.
548 */
549 public boolean isSuspended() {
550 return suspended;
551 }
552
553 /**
554 * Tests if the thread associated with this <tt>ThreadInfo</tt>
555 * is executing native code via the Java Native Interface (JNI).
556 * The JNI native code does not include
557 * the virtual machine support code or the compiled native
558 * code generated by the virtual machine.
559 *
560 * @return <tt>true</tt> if the thread is executing native code;
561 * <tt>false</tt> otherwise.
562 */
563 public boolean isInNative() {
564 return inNative;
565 }
566
567 /**
568 * Returns a string representation of this thread info.
569 * The format of this string depends on the implementation.
570 * The returned string will typically include
571 * the {@linkplain #getThreadName thread name},
572 * the {@linkplain #getThreadId thread ID},
573 * its {@linkplain #getThreadState state},
574 * and a {@linkplain #getStackTrace stack trace} if any.
575 *
576 * @return a string representation of this thread info.
577 */
578 public String toString() {
579 StringBuilder sb = new StringBuilder("\"" + getThreadName()
580 + "\"" + " Id=" + getThreadId() + " "
581 + getThreadState());
582 if (getLockName() != null) {
583 sb.append(" on " + getLockName());
584 }
585 if (getLockOwnerName() != null) {
586 sb.append(" owned by \"" + getLockOwnerName() + "\" Id="
587 + getLockOwnerId());
588 }
589 if (isSuspended()) {
590 sb.append(" (suspended)");
591 }
592 if (isInNative()) {
593 sb.append(" (in native)");
594 }
595 sb.append('\n');
596 int i = 0;
597 for (; i < stackTrace.length && i < MAX_FRAMES; i++) {
598 StackTraceElement ste = stackTrace[i];
599 sb.append("\tat " + ste.toString());
600 sb.append('\n');
601 if (i == 0 && getLockInfo() != null) {
602 Thread.State ts = getThreadState();
603 switch (ts) {
604 case BLOCKED:
605 sb.append("\t- blocked on " + getLockInfo());
606 sb.append('\n');
607 break;
608 case WAITING:
609 sb.append("\t- waiting on " + getLockInfo());
610 sb.append('\n');
611 break;
612 case TIMED_WAITING:
613 sb.append("\t- waiting on " + getLockInfo());
614 sb.append('\n');
615 break;
616 default:
617 }
618 }
619
620 for (MonitorInfo mi : lockedMonitors) {
621 if (mi.getLockedStackDepth() == i) {
622 sb.append("\t- locked " + mi);
623 sb.append('\n');
624 }
625 }
626 }
627 if (i < stackTrace.length) {
628 sb.append("\t...");
629 sb.append('\n');
630 }
631
632 LockInfo[] locks = getLockedSynchronizers();
633 if (locks.length > 0) {
634 sb.append("\n\tNumber of locked synchronizers = "
635 + locks.length);
636 sb.append('\n');
637 for (LockInfo li : locks) {
638 sb.append("\t- " + li);
639 sb.append('\n');
640 }
641 }
642 sb.append('\n');
643 return sb.toString();
644 }
645
646 private static final int MAX_FRAMES = 8;
647
648 /**
649 * Returns a <tt>ThreadInfo</tt> object represented by the
650 * given <tt>CompositeData</tt>.
651 * The given <tt>CompositeData</tt> must contain the following attributes
652 * unless otherwise specified below:
653 * <blockquote>
654 * <table border>
655 * <tr>
656 * <th align=left>Attribute Name</th>
657 * <th align=left>Type</th>
658 * </tr>
659 * <tr>
660 * <td>threadId</td>
661 * <td><tt>java.lang.Long</tt></td>
662 * </tr>
663 * <tr>
664 * <td>threadName</td>
665 * <td><tt>java.lang.String</tt></td>
666 * </tr>
667 * <tr>
668 * <td>threadState</td>
669 * <td><tt>java.lang.String</tt></td>
670 * </tr>
671 * <tr>
672 * <td>suspended</td>
673 * <td><tt>java.lang.Boolean</tt></td>
674 * </tr>
675 * <tr>
676 * <td>inNative</td>
677 * <td><tt>java.lang.Boolean</tt></td>
678 * </tr>
679 * <tr>
680 * <td>blockedCount</td>
681 * <td><tt>java.lang.Long</tt></td>
682 * </tr>
683 * <tr>
684 * <td>blockedTime</td>
685 * <td><tt>java.lang.Long</tt></td>
686 * </tr>
687 * <tr>
688 * <td>waitedCount</td>
689 * <td><tt>java.lang.Long</tt></td>
690 * </tr>
691 * <tr>
692 * <td>waitedTime</td>
693 * <td><tt>java.lang.Long</tt></td>
694 * </tr>
695 * <tr>
696 * <td>lockInfo</td>
697 * <td><tt>javax.management.openmbean.CompositeData</tt>
698 * - the mapped type for {@link LockInfo} as specified in the
699 * <a href="../../../javax/management/MXBean.html#mapping-rules">
700 * type mapping rules</a> of
701 * {@linkplain javax.management.MXBean MXBeans}.
702 * <p>
703 * If <tt>cd</tt> does not contain this attribute,
704 * the <tt>LockInfo</tt> object will be constructed from
705 * the value of the <tt>lockName</tt> attribute. </td>
706 * </tr>
707 * <tr>
708 * <td>lockName</td>
709 * <td><tt>java.lang.String</tt></td>
710 * </tr>
711 * <tr>
712 * <td>lockOwnerId</td>
713 * <td><tt>java.lang.Long</tt></td>
714 * </tr>
715 * <tr>
716 * <td>lockOwnerName</td>
717 * <td><tt>java.lang.String</tt></td>
718 * </tr>
719 * <tr>
720 * <td><a name="StackTrace">stackTrace</a></td>
721 * <td><tt>javax.management.openmbean.CompositeData[]</tt>
722 * <p>
723 * Each element is a <tt>CompositeData</tt> representing
724 * StackTraceElement containing the following attributes:
725 * <blockquote>
726 * <table cellspacing=1 cellpadding=0>
727 * <tr>
728 * <th align=left>Attribute Name</th>
729 * <th align=left>Type</th>
730 * </tr>
731 * <tr>
732 * <td>className</td>
733 * <td><tt>java.lang.String</tt></td>
734 * </tr>
735 * <tr>
736 * <td>methodName</td>
737 * <td><tt>java.lang.String</tt></td>
738 * </tr>
739 * <tr>
740 * <td>fileName</td>
741 * <td><tt>java.lang.String</tt></td>
742 * </tr>
743 * <tr>
744 * <td>lineNumber</td>
745 * <td><tt>java.lang.Integer</tt></td>
746 * </tr>
747 * <tr>
748 * <td>nativeMethod</td>
749 * <td><tt>java.lang.Boolean</tt></td>
750 * </tr>
751 * </table>
752 * </blockquote>
753 * </td>
754 * </tr>
755 * <tr>
756 * <td>lockedMonitors</td>
757 * <td><tt>javax.management.openmbean.CompositeData[]</tt>
758 * whose element type is the mapped type for
759 * {@link MonitorInfo} as specified in the
760 * {@link MonitorInfo#from Monitor.from} method.
761 * <p>
762 * If <tt>cd</tt> does not contain this attribute,
763 * this attribute will be set to an empty array. </td>
764 * </tr>
765 * <tr>
766 * <td>lockedSynchronizers</td>
767 * <td><tt>javax.management.openmbean.CompositeData[]</tt>
768 * whose element type is the mapped type for
769 * {@link LockInfo} as specified in the
770 * <a href="../../../javax/management/MXBean.html#mapping-rules">
771 * type mapping rules</a> of
772 * {@linkplain javax.management.MXBean MXBeans}.
773 * <p>
774 * If <tt>cd</tt> does not contain this attribute,
775 * this attribute will be set to an empty array. </td>
776 * </tr>
777 * </table>
778 * </blockquote>
779 *
780 * @param cd <tt>CompositeData</tt> representing a <tt>ThreadInfo</tt>
781 *
782 * @throws IllegalArgumentException if <tt>cd</tt> does not
783 * represent a <tt>ThreadInfo</tt> with the attributes described
784 * above.
785 *
786 * @return a <tt>ThreadInfo</tt> object represented
787 * by <tt>cd</tt> if <tt>cd</tt> is not <tt>null</tt>;
788 * <tt>null</tt> otherwise.
789 */
790 public static ThreadInfo from(CompositeData cd) {
791 if (cd == null) {
792 return null;
793 }
794
795 if (cd instanceof ThreadInfoCompositeData) {
796 return ((ThreadInfoCompositeData) cd).getThreadInfo();
797 } else {
798 return new ThreadInfo(cd);
799 }
800 }
801
802 /**
803 * Returns an array of {@link MonitorInfo} objects, each of which
804 * represents an object monitor currently locked by the thread
805 * associated with this <tt>ThreadInfo</tt>.
806 * If no locked monitor was requested for this thread info or
807 * no monitor is locked by the thread, this method
808 * will return a zero-length array.
809 *
810 * @return an array of <tt>MonitorInfo</tt> objects representing
811 * the object monitors locked by the thread.
812 *
813 * @since 1.6
814 */
815 public MonitorInfo[] getLockedMonitors() {
816 return lockedMonitors;
817 }
818
819 /**
820 * Returns an array of {@link LockInfo} objects, each of which
821 * represents an <a href="LockInfo.html#OwnableSynchronizer">ownable
822 * synchronizer</a> currently locked by the thread associated with
823 * this <tt>ThreadInfo</tt>. If no locked synchronizer was
824 * requested for this thread info or no synchronizer is locked by
825 * the thread, this method will return a zero-length array.
826 *
827 * @return an array of <tt>LockInfo</tt> objects representing
828 * the ownable synchronizers locked by the thread.
829 *
830 * @since 1.6
831 */
832 public LockInfo[] getLockedSynchronizers() {
833 // represents an <a href="LockInfo.html#OwnableSynchronizer">
834 return lockedSynchronizers;
835 }
836
837 private static final StackTraceElement[] NO_STACK_TRACE = new StackTraceElement[0];
838 }
|