Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.management/share/classes/java/lang/management/ThreadInfo.java
41159 views
1
/*
2
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package java.lang.management;
27
28
import javax.management.openmbean.ArrayType;
29
import javax.management.openmbean.CompositeData;
30
import sun.management.ManagementFactoryHelper;
31
import sun.management.ThreadInfoCompositeData;
32
import static java.lang.Thread.State.*;
33
34
/**
35
* Thread information. {@code ThreadInfo} contains the information
36
* about a thread including:
37
* <h2>General thread information</h2>
38
* <ul>
39
* <li>Thread ID.</li>
40
* <li>Name of the thread.</li>
41
* <li>Whether a thread is a daemon thread</li>
42
* </ul>
43
*
44
* <h2>Execution information</h2>
45
* <ul>
46
* <li>Thread state.</li>
47
* <li>The object upon which the thread is blocked due to:
48
* <ul>
49
* <li>waiting to enter a synchronization block/method, or</li>
50
* <li>waiting to be notified in a {@link Object#wait Object.wait} method,
51
* or</li>
52
* <li>parking due to a {@link java.util.concurrent.locks.LockSupport#park
53
* LockSupport.park} call.</li>
54
* </ul>
55
* </li>
56
* <li>The ID of the thread that owns the object
57
* that the thread is blocked.</li>
58
* <li>Stack trace of the thread.</li>
59
* <li>List of object monitors locked by the thread.</li>
60
* <li>List of <a href="LockInfo.html#OwnableSynchronizer">
61
* ownable synchronizers</a> locked by the thread.</li>
62
* <li>Thread priority</li>
63
* </ul>
64
*
65
* <h3><a id="SyncStats">Synchronization Statistics</a></h3>
66
* <ul>
67
* <li>The number of times that the thread has blocked for
68
* synchronization or waited for notification.</li>
69
* <li>The accumulated elapsed time that the thread has blocked
70
* for synchronization or waited for notification
71
* since {@link ThreadMXBean#setThreadContentionMonitoringEnabled
72
* thread contention monitoring}
73
* was enabled. Some Java virtual machine implementation
74
* may not support this. The
75
* {@link ThreadMXBean#isThreadContentionMonitoringSupported()}
76
* method can be used to determine if a Java virtual machine
77
* supports this.</li>
78
* </ul>
79
*
80
* <p>This thread information class is designed for use in monitoring of
81
* the system, not for synchronization control.
82
*
83
* <h3>MXBean Mapping</h3>
84
* {@code ThreadInfo} is mapped to a {@link CompositeData CompositeData}
85
* with attributes as specified in
86
* the {@link #from from} method.
87
*
88
* @see ThreadMXBean#getThreadInfo
89
* @see ThreadMXBean#dumpAllThreads
90
*
91
* @author Mandy Chung
92
* @since 1.5
93
*/
94
95
public class ThreadInfo {
96
private String threadName;
97
private long threadId;
98
private long blockedTime;
99
private long blockedCount;
100
private long waitedTime;
101
private long waitedCount;
102
private LockInfo lock;
103
private String lockName;
104
private long lockOwnerId;
105
private String lockOwnerName;
106
private boolean daemon;
107
private boolean inNative;
108
private boolean suspended;
109
private Thread.State threadState;
110
private int priority;
111
private StackTraceElement[] stackTrace;
112
private MonitorInfo[] lockedMonitors;
113
private LockInfo[] lockedSynchronizers;
114
private static MonitorInfo[] EMPTY_MONITORS = new MonitorInfo[0];
115
private static LockInfo[] EMPTY_SYNCS = new LockInfo[0];
116
117
/**
118
* Constructor of ThreadInfo created by the JVM
119
*
120
* @param t Thread
121
* @param state Thread state
122
* @param lockObj Object on which the thread is blocked
123
* @param lockOwner the thread holding the lock
124
* @param blockedCount Number of times blocked to enter a lock
125
* @param blockedTime Approx time blocked to enter a lock
126
* @param waitedCount Number of times waited on a lock
127
* @param waitedTime Approx time waited on a lock
128
* @param stackTrace Thread stack trace
129
*/
130
private ThreadInfo(Thread t, int state, Object lockObj, Thread lockOwner,
131
long blockedCount, long blockedTime,
132
long waitedCount, long waitedTime,
133
StackTraceElement[] stackTrace) {
134
initialize(t, state, lockObj, lockOwner,
135
blockedCount, blockedTime,
136
waitedCount, waitedTime, stackTrace,
137
EMPTY_MONITORS, EMPTY_SYNCS);
138
}
139
140
/**
141
* Constructor of ThreadInfo created by the JVM
142
* for {@link ThreadMXBean#getThreadInfo(long[],boolean,boolean)}
143
* and {@link ThreadMXBean#dumpAllThreads}
144
*
145
* @param t Thread
146
* @param state Thread state
147
* @param lockObj Object on which the thread is blocked
148
* @param lockOwner the thread holding the lock
149
* @param blockedCount Number of times blocked to enter a lock
150
* @param blockedTime Approx time blocked to enter a lock
151
* @param waitedCount Number of times waited on a lock
152
* @param waitedTime Approx time waited on a lock
153
* @param stackTrace Thread stack trace
154
* @param monitors List of locked monitors
155
* @param stackDepths List of stack depths
156
* @param synchronizers List of locked synchronizers
157
*/
158
private ThreadInfo(Thread t, int state, Object lockObj, Thread lockOwner,
159
long blockedCount, long blockedTime,
160
long waitedCount, long waitedTime,
161
StackTraceElement[] stackTrace,
162
Object[] monitors,
163
int[] stackDepths,
164
Object[] synchronizers) {
165
int numMonitors = (monitors == null ? 0 : monitors.length);
166
MonitorInfo[] lockedMonitors;
167
if (numMonitors == 0) {
168
lockedMonitors = EMPTY_MONITORS;
169
} else {
170
lockedMonitors = new MonitorInfo[numMonitors];
171
for (int i = 0; i < numMonitors; i++) {
172
Object lock = monitors[i];
173
String className = lock.getClass().getName();
174
int identityHashCode = System.identityHashCode(lock);
175
int depth = stackDepths[i];
176
StackTraceElement ste = (depth >= 0 ? stackTrace[depth]
177
: null);
178
lockedMonitors[i] = new MonitorInfo(className,
179
identityHashCode,
180
depth,
181
ste);
182
}
183
}
184
185
int numSyncs = (synchronizers == null ? 0 : synchronizers.length);
186
LockInfo[] lockedSynchronizers;
187
if (numSyncs == 0) {
188
lockedSynchronizers = EMPTY_SYNCS;
189
} else {
190
lockedSynchronizers = new LockInfo[numSyncs];
191
for (int i = 0; i < numSyncs; i++) {
192
Object lock = synchronizers[i];
193
String className = lock.getClass().getName();
194
int identityHashCode = System.identityHashCode(lock);
195
lockedSynchronizers[i] = new LockInfo(className,
196
identityHashCode);
197
}
198
}
199
200
initialize(t, state, lockObj, lockOwner,
201
blockedCount, blockedTime,
202
waitedCount, waitedTime, stackTrace,
203
lockedMonitors, lockedSynchronizers);
204
}
205
206
/**
207
* Initialize ThreadInfo object
208
*
209
* @param t Thread
210
* @param state Thread state
211
* @param lockObj Object on which the thread is blocked
212
* @param lockOwner the thread holding the lock
213
* @param blockedCount Number of times blocked to enter a lock
214
* @param blockedTime Approx time blocked to enter a lock
215
* @param waitedCount Number of times waited on a lock
216
* @param waitedTime Approx time waited on a lock
217
* @param stackTrace Thread stack trace
218
* @param lockedMonitors List of locked monitors
219
* @param lockedSynchronizers List of locked synchronizers
220
*/
221
private void initialize(Thread t, int state, Object lockObj, Thread lockOwner,
222
long blockedCount, long blockedTime,
223
long waitedCount, long waitedTime,
224
StackTraceElement[] stackTrace,
225
MonitorInfo[] lockedMonitors,
226
LockInfo[] lockedSynchronizers) {
227
this.threadId = t.getId();
228
this.threadName = t.getName();
229
this.threadState = ManagementFactoryHelper.toThreadState(state);
230
this.suspended = ManagementFactoryHelper.isThreadSuspended(state);
231
this.inNative = ManagementFactoryHelper.isThreadRunningNative(state);
232
this.blockedCount = blockedCount;
233
this.blockedTime = blockedTime;
234
this.waitedCount = waitedCount;
235
this.waitedTime = waitedTime;
236
this.daemon = t.isDaemon();
237
this.priority = t.getPriority();
238
239
if (lockObj == null) {
240
this.lock = null;
241
this.lockName = null;
242
} else {
243
this.lock = new LockInfo(lockObj);
244
this.lockName =
245
lock.getClassName() + '@' +
246
Integer.toHexString(lock.getIdentityHashCode());
247
}
248
if (lockOwner == null) {
249
this.lockOwnerId = -1;
250
this.lockOwnerName = null;
251
} else {
252
this.lockOwnerId = lockOwner.getId();
253
this.lockOwnerName = lockOwner.getName();
254
}
255
if (stackTrace == null) {
256
this.stackTrace = NO_STACK_TRACE;
257
} else {
258
this.stackTrace = stackTrace;
259
}
260
this.lockedMonitors = lockedMonitors;
261
this.lockedSynchronizers = lockedSynchronizers;
262
}
263
264
/*
265
* Constructs a {@code ThreadInfo} object from a
266
* {@link CompositeData CompositeData}.
267
*
268
* @throws IllegalArgumentException if the given CompositeData does not
269
* contain all of the attributes defined for ThreadInfo of version <= N.
270
*
271
* @see ThreadInfo#from
272
*/
273
private ThreadInfo(CompositeData cd) {
274
ThreadInfoCompositeData ticd = ThreadInfoCompositeData.getInstance(cd);
275
276
threadId = ticd.threadId();
277
threadName = ticd.threadName();
278
blockedTime = ticd.blockedTime();
279
blockedCount = ticd.blockedCount();
280
waitedTime = ticd.waitedTime();
281
waitedCount = ticd.waitedCount();
282
lockName = ticd.lockName();
283
lockOwnerId = ticd.lockOwnerId();
284
lockOwnerName = ticd.lockOwnerName();
285
threadState = ticd.threadState();
286
suspended = ticd.suspended();
287
inNative = ticd.inNative();
288
stackTrace = ticd.stackTrace();
289
lock = ticd.lockInfo();
290
lockedMonitors = ticd.lockedMonitors();
291
lockedSynchronizers = ticd.lockedSynchronizers();
292
daemon = ticd.isDaemon();
293
priority = ticd.getPriority();
294
}
295
296
/**
297
* Returns the ID of the thread associated with this {@code ThreadInfo}.
298
*
299
* @return the ID of the associated thread.
300
*/
301
public long getThreadId() {
302
return threadId;
303
}
304
305
/**
306
* Returns the name of the thread associated with this {@code ThreadInfo}.
307
*
308
* @return the name of the associated thread.
309
*/
310
public String getThreadName() {
311
return threadName;
312
}
313
314
/**
315
* Returns the state of the thread associated with this {@code ThreadInfo}.
316
*
317
* @return {@code Thread.State} of the associated thread.
318
*/
319
public Thread.State getThreadState() {
320
return threadState;
321
}
322
323
/**
324
* Returns the approximate accumulated elapsed time (in milliseconds)
325
* that the thread associated with this {@code ThreadInfo}
326
* has blocked to enter or reenter a monitor
327
* since thread contention monitoring is enabled.
328
* I.e. the total accumulated time the thread has been in the
329
* {@link java.lang.Thread.State#BLOCKED BLOCKED} state since thread
330
* contention monitoring was last enabled.
331
* This method returns {@code -1} if thread contention monitoring
332
* is disabled.
333
*
334
* <p>The Java virtual machine may measure the time with a high
335
* resolution timer. This statistic is reset when
336
* the thread contention monitoring is reenabled.
337
*
338
* @return the approximate accumulated elapsed time in milliseconds
339
* that a thread entered the {@code BLOCKED} state;
340
* {@code -1} if thread contention monitoring is disabled.
341
*
342
* @throws java.lang.UnsupportedOperationException if the Java
343
* virtual machine does not support this operation.
344
*
345
* @see ThreadMXBean#isThreadContentionMonitoringSupported
346
* @see ThreadMXBean#setThreadContentionMonitoringEnabled
347
*/
348
public long getBlockedTime() {
349
return blockedTime;
350
}
351
352
/**
353
* Returns the total number of times that
354
* the thread associated with this {@code ThreadInfo}
355
* blocked to enter or reenter a monitor.
356
* I.e. the number of times a thread has been in the
357
* {@link java.lang.Thread.State#BLOCKED BLOCKED} state.
358
*
359
* @return the total number of times that the thread
360
* entered the {@code BLOCKED} state.
361
*/
362
public long getBlockedCount() {
363
return blockedCount;
364
}
365
366
/**
367
* Returns the approximate accumulated elapsed time (in milliseconds)
368
* that the thread associated with this {@code ThreadInfo}
369
* has waited for notification
370
* since thread contention monitoring is enabled.
371
* I.e. the total accumulated time the thread has been in the
372
* {@link java.lang.Thread.State#WAITING WAITING}
373
* or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state
374
* since thread contention monitoring is enabled.
375
* This method returns {@code -1} if thread contention monitoring
376
* is disabled.
377
*
378
* <p>The Java virtual machine may measure the time with a high
379
* resolution timer. This statistic is reset when
380
* the thread contention monitoring is reenabled.
381
*
382
* @return the approximate accumulated elapsed time in milliseconds
383
* that a thread has been in the {@code WAITING} or
384
* {@code TIMED_WAITING} state;
385
* {@code -1} if thread contention monitoring is disabled.
386
*
387
* @throws java.lang.UnsupportedOperationException if the Java
388
* virtual machine does not support this operation.
389
*
390
* @see ThreadMXBean#isThreadContentionMonitoringSupported
391
* @see ThreadMXBean#setThreadContentionMonitoringEnabled
392
*/
393
public long getWaitedTime() {
394
return waitedTime;
395
}
396
397
/**
398
* Returns the total number of times that
399
* the thread associated with this {@code ThreadInfo}
400
* waited for notification.
401
* I.e. the number of times that a thread has been
402
* in the {@link java.lang.Thread.State#WAITING WAITING}
403
* or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state.
404
*
405
* @return the total number of times that the thread
406
* was in the {@code WAITING} or {@code TIMED_WAITING} state.
407
*/
408
public long getWaitedCount() {
409
return waitedCount;
410
}
411
412
/**
413
* Returns the {@code LockInfo} of an object for which
414
* the thread associated with this {@code ThreadInfo}
415
* is blocked waiting.
416
* A thread can be blocked waiting for one of the following:
417
* <ul>
418
* <li>an object monitor to be acquired for entering or reentering
419
* a synchronization block/method.
420
* <br>The thread is in the {@link java.lang.Thread.State#BLOCKED BLOCKED}
421
* state waiting to enter the {@code synchronized} statement
422
* or method.
423
* </li>
424
* <li>an object monitor to be notified by another thread.
425
* <br>The thread is in the {@link java.lang.Thread.State#WAITING WAITING}
426
* or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state
427
* due to a call to the {@link Object#wait Object.wait} method.
428
* </li>
429
* <li>a synchronization object responsible for the thread parking.
430
* <br>The thread is in the {@link java.lang.Thread.State#WAITING WAITING}
431
* or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state
432
* due to a call to the
433
* {@link java.util.concurrent.locks.LockSupport#park(Object)
434
* LockSupport.park} method. The synchronization object
435
* is the object returned from
436
* {@link java.util.concurrent.locks.LockSupport#getBlocker
437
* LockSupport.getBlocker} method. Typically it is an
438
* <a href="LockInfo.html#OwnableSynchronizer"> ownable synchronizer</a>
439
* or a {@link java.util.concurrent.locks.Condition Condition}.</li>
440
* </ul>
441
*
442
* <p>This method returns {@code null} if the thread is not in any of
443
* the above conditions.
444
*
445
* @return {@code LockInfo} of an object for which the thread
446
* is blocked waiting if any; {@code null} otherwise.
447
* @since 1.6
448
*/
449
public LockInfo getLockInfo() {
450
return lock;
451
}
452
453
/**
454
* Returns the {@link LockInfo#toString string representation}
455
* of an object for which the thread associated with this
456
* {@code ThreadInfo} is blocked waiting.
457
* This method is equivalent to calling:
458
* <blockquote>
459
* <pre>
460
* getLockInfo().toString()
461
* </pre></blockquote>
462
*
463
* <p>This method will return {@code null} if this thread is not blocked
464
* waiting for any object or if the object is not owned by any thread.
465
*
466
* @return the string representation of the object on which
467
* the thread is blocked if any;
468
* {@code null} otherwise.
469
*
470
* @see #getLockInfo
471
*/
472
public String getLockName() {
473
return lockName;
474
}
475
476
/**
477
* Returns the ID of the thread which owns the object
478
* for which the thread associated with this {@code ThreadInfo}
479
* is blocked waiting.
480
* This method will return {@code -1} if this thread is not blocked
481
* waiting for any object or if the object is not owned by any thread.
482
*
483
* @return the thread ID of the owner thread of the object
484
* this thread is blocked on;
485
* {@code -1} if this thread is not blocked
486
* or if the object is not owned by any thread.
487
*
488
* @see #getLockInfo
489
*/
490
public long getLockOwnerId() {
491
return lockOwnerId;
492
}
493
494
/**
495
* Returns the name of the thread which owns the object
496
* for which the thread associated with this {@code ThreadInfo}
497
* is blocked waiting.
498
* This method will return {@code null} if this thread is not blocked
499
* waiting for any object or if the object is not owned by any thread.
500
*
501
* @return the name of the thread that owns the object
502
* this thread is blocked on;
503
* {@code null} if this thread is not blocked
504
* or if the object is not owned by any thread.
505
*
506
* @see #getLockInfo
507
*/
508
public String getLockOwnerName() {
509
return lockOwnerName;
510
}
511
512
/**
513
* Returns the stack trace of the thread
514
* associated with this {@code ThreadInfo}.
515
* If no stack trace was requested for this thread info, this method
516
* will return a zero-length array.
517
* If the returned array is of non-zero length then the first element of
518
* the array represents the top of the stack, which is the most recent
519
* method invocation in the sequence. The last element of the array
520
* represents the bottom of the stack, which is the least recent method
521
* invocation in the sequence.
522
*
523
* <p>Some Java virtual machines may, under some circumstances, omit one
524
* or more stack frames from the stack trace. In the extreme case,
525
* a virtual machine that has no stack trace information concerning
526
* the thread associated with this {@code ThreadInfo}
527
* is permitted to return a zero-length array from this method.
528
*
529
* @return an array of {@code StackTraceElement} objects of the thread.
530
*/
531
public StackTraceElement[] getStackTrace() {
532
return stackTrace.clone();
533
}
534
535
/**
536
* Tests if the thread associated with this {@code ThreadInfo}
537
* is suspended. This method returns {@code true} if
538
* {@link Thread#suspend} has been called.
539
*
540
* @return {@code true} if the thread is suspended;
541
* {@code false} otherwise.
542
*/
543
public boolean isSuspended() {
544
return suspended;
545
}
546
547
/**
548
* Tests if the thread associated with this {@code ThreadInfo}
549
* is executing native code via the Java Native Interface (JNI).
550
* The JNI native code does not include
551
* the virtual machine support code or the compiled native
552
* code generated by the virtual machine.
553
*
554
* @return {@code true} if the thread is executing native code;
555
* {@code false} otherwise.
556
*/
557
public boolean isInNative() {
558
return inNative;
559
}
560
561
/**
562
* Tests if the thread associated with this {@code ThreadInfo} is
563
* a {@linkplain Thread#isDaemon daemon thread}.
564
*
565
* @return {@code true} if the thread is a daemon thread,
566
* {@code false} otherwise.
567
* @see Thread#isDaemon
568
* @since 9
569
*/
570
public boolean isDaemon() {
571
return daemon;
572
}
573
574
/**
575
* Returns the {@linkplain Thread#getPriority() thread priority} of the
576
* thread associated with this {@code ThreadInfo}.
577
*
578
* @return The priority of the thread associated with this
579
* {@code ThreadInfo}.
580
* @since 9
581
*/
582
public int getPriority() {
583
return priority;
584
}
585
586
/**
587
* Returns a string representation of this thread info.
588
* The format of this string depends on the implementation.
589
* The returned string will typically include
590
* the {@linkplain #getThreadName thread name},
591
* the {@linkplain #getThreadId thread ID},
592
* its {@linkplain #getThreadState state},
593
* and a {@linkplain #getStackTrace stack trace} if any.
594
*
595
* @return a string representation of this thread info.
596
*/
597
public String toString() {
598
StringBuilder sb = new StringBuilder("\"" + getThreadName() + "\"" +
599
(daemon ? " daemon" : "") +
600
" prio=" + priority +
601
" Id=" + getThreadId() + " " +
602
getThreadState());
603
if (getLockName() != null) {
604
sb.append(" on " + getLockName());
605
}
606
if (getLockOwnerName() != null) {
607
sb.append(" owned by \"" + getLockOwnerName() +
608
"\" Id=" + getLockOwnerId());
609
}
610
if (isSuspended()) {
611
sb.append(" (suspended)");
612
}
613
if (isInNative()) {
614
sb.append(" (in native)");
615
}
616
sb.append('\n');
617
int i = 0;
618
for (; i < stackTrace.length && i < MAX_FRAMES; i++) {
619
StackTraceElement ste = stackTrace[i];
620
sb.append("\tat " + ste.toString());
621
sb.append('\n');
622
if (i == 0 && getLockInfo() != null) {
623
Thread.State ts = getThreadState();
624
switch (ts) {
625
case BLOCKED:
626
sb.append("\t- blocked on " + getLockInfo());
627
sb.append('\n');
628
break;
629
case WAITING:
630
sb.append("\t- waiting on " + getLockInfo());
631
sb.append('\n');
632
break;
633
case TIMED_WAITING:
634
sb.append("\t- waiting on " + getLockInfo());
635
sb.append('\n');
636
break;
637
default:
638
}
639
}
640
641
for (MonitorInfo mi : lockedMonitors) {
642
if (mi.getLockedStackDepth() == i) {
643
sb.append("\t- locked " + mi);
644
sb.append('\n');
645
}
646
}
647
}
648
if (i < stackTrace.length) {
649
sb.append("\t...");
650
sb.append('\n');
651
}
652
653
LockInfo[] locks = getLockedSynchronizers();
654
if (locks.length > 0) {
655
sb.append("\n\tNumber of locked synchronizers = " + locks.length);
656
sb.append('\n');
657
for (LockInfo li : locks) {
658
sb.append("\t- " + li);
659
sb.append('\n');
660
}
661
}
662
sb.append('\n');
663
return sb.toString();
664
}
665
private static final int MAX_FRAMES = 8;
666
667
/**
668
* Returns a {@code ThreadInfo} object represented by the
669
* given {@code CompositeData}.
670
*
671
* <a id="attributes"></a>
672
* A {@code CompositeData} representing a {@code ThreadInfo} of
673
* version <em>N</em> must contain all of the attributes defined
674
* in version &le; <em>N</em> unless specified otherwise.
675
* The same rule applies the composite type of the given
676
* {@code CompositeData} and transitively to attributes whose
677
* {@linkplain CompositeData#getCompositeType() type} or
678
* {@linkplain ArrayType#getElementOpenType() component type} is
679
* {@code CompositeType}.
680
* <p>
681
* A {@code CompositeData} representing {@code ThreadInfo} of
682
* version <em>N</em> contains {@code "stackTrace"} attribute and
683
* {@code "lockedMonitors"} attribute representing
684
* an array of {@code StackTraceElement} and
685
* an array of {@link MonitorInfo} respectively
686
* and their types are of version <em>N</em>.
687
* The {@code "lockedStackFrame"} attribute in
688
* {@link MonitorInfo#from(CompositeData) MonitorInfo}'s composite type
689
* must represent {@code StackTraceElement} of the same version <em>N</em>.
690
* Otherwise, this method will throw {@code IllegalArgumentException}.
691
*
692
* <table class="striped" style="margin-left:2em">
693
* <caption style="display:none">The attributes and their types for ThreadInfo's composite data</caption>
694
* <thead>
695
* <tr>
696
* <th scope="col">Attribute Name</th>
697
* <th scope="col">Type</th>
698
* <th scope="col">Since</th>
699
* </tr>
700
* </thead>
701
* <tbody style="text-align:left">
702
* <tr>
703
* <th scope="row">threadId</th>
704
* <td>{@code java.lang.Long}</td>
705
* <td>5</td>
706
* </tr>
707
* <tr>
708
* <th scope="row">threadName</th>
709
* <td>{@code java.lang.String}</td>
710
* <td>5</td>
711
* </tr>
712
* <tr>
713
* <th scope="row">threadState</th>
714
* <td>{@code java.lang.String}</td>
715
* <td>5</td>
716
* </tr>
717
* <tr>
718
* <th scope="row">suspended</th>
719
* <td>{@code java.lang.Boolean}</td>
720
* <td>5</td>
721
* </tr>
722
* <tr>
723
* <th scope="row">inNative</th>
724
* <td>{@code java.lang.Boolean}</td>
725
* <td>5</td>
726
* </tr>
727
* <tr>
728
* <th scope="row">blockedCount</th>
729
* <td>{@code java.lang.Long}</td>
730
* <td>5</td>
731
* </tr>
732
* <tr>
733
* <th scope="row">blockedTime</th>
734
* <td>{@code java.lang.Long}</td>
735
* <td>5</td>
736
* </tr>
737
* <tr>
738
* <th scope="row">waitedCount</th>
739
* <td>{@code java.lang.Long}</td>
740
* <td>5</td>
741
* </tr>
742
* <tr>
743
* <th scope="row">waitedTime</th>
744
* <td>{@code java.lang.Long}</td>
745
* <td>5</td>
746
* </tr>
747
* <tr>
748
* <th scope="row">lockName</th>
749
* <td>{@code java.lang.String}</td>
750
* <td>5</td>
751
* </tr>
752
* <tr>
753
* <th scope="row">lockOwnerId</th>
754
* <td>{@code java.lang.Long}</td>
755
* <td>5</td>
756
* </tr>
757
* <tr>
758
* <th scope="row">lockOwnerName</th>
759
* <td>{@code java.lang.String}</td>
760
* <td>5</td>
761
* </tr>
762
* <tr>
763
* <th scope="row"><a id="StackTrace">stackTrace</a></th>
764
* <td>{@code javax.management.openmbean.CompositeData[]}, each element
765
* is a {@code CompositeData} representing {@code StackTraceElement}
766
* as specified <a href="#stackTraceElement">below</a>.
767
* </td>
768
* <td>5</td>
769
* </tr>
770
* <tr>
771
* <th scope="row">lockInfo</th>
772
* <td>{@code javax.management.openmbean.CompositeData}
773
* - the mapped type for {@link LockInfo} as specified in the
774
* {@link LockInfo#from} method.
775
* <p>
776
* If the given {@code CompositeData} does not contain this attribute,
777
* the {@code LockInfo} object will be constructed from
778
* the value of the {@code lockName} attribute.</td>
779
* <td>6</td>
780
* </tr>
781
* <tr>
782
* <th scope="row">lockedMonitors</th>
783
* <td>{@code javax.management.openmbean.CompositeData[]}
784
* whose element type is the mapped type for
785
* {@link MonitorInfo} as specified in the
786
* {@link MonitorInfo#from MonitorInfo.from} method.
787
* <p>
788
* If the given {@code CompositeData} does not contain this attribute,
789
* this attribute will be set to an empty array.</td>
790
* <td>6</td>
791
* </tr>
792
* <tr>
793
* <th scope="row">lockedSynchronizers</th>
794
* <td>{@code javax.management.openmbean.CompositeData[]}
795
* whose element type is the mapped type for
796
* {@link LockInfo} as specified in the {@link LockInfo#from} method.
797
* <p>
798
* If the given {@code CompositeData} does not contain this attribute,
799
* this attribute will be set to an empty array.</td>
800
* <td>6</td>
801
* </tr>
802
* <tr>
803
* <th scope="row">daemon</th>
804
* <td>{@code java.lang.Boolean}
805
* <p>
806
* If the given {@code CompositeData} does not contain this attribute,
807
* this attribute will be set to {@code false}.</td>
808
* <td>9</td>
809
* </tr>
810
* <tr>
811
* <th scope="row">priority</th>
812
* <td>{@code java.lang.Integer}
813
* <p>
814
* If the given {@code CompositeData} does not contain this attribute,
815
* This attribute will be set to {@link Thread#NORM_PRIORITY}.</td>
816
* <td>9</td>
817
* </tr>
818
* </tbody>
819
* </table>
820
*
821
* <a id="stackTraceElement">A {@code CompositeData} representing
822
* {@code StackTraceElement}</a> of version <em>N</em> must contain
823
* all of the attributes defined in version &le; <em>N</em>
824
* unless specified otherwise.
825
*
826
* <table class="striped" style="margin-left:2em">
827
* <caption style="display:none">The attributes and their types for StackTraceElement's composite data</caption>
828
* <thead style="text-align:center">
829
* <tr>
830
* <th scope="col">Attribute Name</th>
831
* <th scope="col">Type</th>
832
* <th scope="col">Since</th>
833
* </tr>
834
* </thead>
835
* <tbody style="text-align:left">
836
* <tr>
837
* <th scope="row">classLoaderName</th>
838
* <td>{@code java.lang.String}</td>
839
* <td>9</td>
840
* </tr>
841
* <tr>
842
* <th scope="row">moduleName</th>
843
* <td>{@code java.lang.String}</td>
844
* <td>9</td>
845
* </tr>
846
* <tr>
847
* <th scope="row">moduleVersion</th>
848
* <td>{@code java.lang.String}</td>
849
* <td>9</td>
850
* </tr>
851
* <tr>
852
* <th scope="row">className</th>
853
* <td>{@code java.lang.String}</td>
854
* <td>5</td>
855
* </tr>
856
* <tr>
857
* <th scope="row">methodName</th>
858
* <td>{@code java.lang.String}</td>
859
* <td>5</td>
860
* </tr>
861
* <tr>
862
* <th scope="row">fileName</th>
863
* <td>{@code java.lang.String}</td>
864
* <td>5</td>
865
* </tr>
866
* <tr>
867
* <th scope="row">lineNumber</th>
868
* <td>{@code java.lang.Integer}</td>
869
* <td>5</td>
870
* </tr>
871
* <tr>
872
* <th scope="row">nativeMethod</th>
873
* <td>{@code java.lang.Boolean}</td>
874
* <td>5</td>
875
* </tr>
876
* </tbody>
877
* </table>
878
*
879
* @param cd {@code CompositeData} representing a {@code ThreadInfo}
880
*
881
* @throws IllegalArgumentException if the given {@code cd} and
882
* its composite type does not contain all of
883
* <a href="#attributes">the attributes</a> defined for a
884
* {@code ThreadInfo} of a specific runtime version.
885
*
886
* @return a {@code ThreadInfo} object represented
887
* by {@code cd} if {@code cd} is not {@code null};
888
* {@code null} otherwise.
889
*
890
* @revised 9
891
*/
892
public static ThreadInfo from(CompositeData cd) {
893
if (cd == null) {
894
return null;
895
}
896
897
if (cd instanceof ThreadInfoCompositeData) {
898
return ((ThreadInfoCompositeData) cd).getThreadInfo();
899
} else {
900
return new ThreadInfo(cd);
901
}
902
}
903
904
/**
905
* Returns an array of {@link MonitorInfo} objects, each of which
906
* represents an object monitor currently locked by the thread
907
* associated with this {@code ThreadInfo}.
908
* If no locked monitor was requested for this thread info or
909
* no monitor is locked by the thread, this method
910
* will return a zero-length array.
911
*
912
* @return an array of {@code MonitorInfo} objects representing
913
* the object monitors locked by the thread.
914
*
915
* @since 1.6
916
*/
917
public MonitorInfo[] getLockedMonitors() {
918
return lockedMonitors.clone();
919
}
920
921
/**
922
* Returns an array of {@link LockInfo} objects, each of which
923
* represents an <a href="LockInfo.html#OwnableSynchronizer">ownable
924
* synchronizer</a> currently locked by the thread associated with
925
* this {@code ThreadInfo}. If no locked synchronizer was
926
* requested for this thread info or no synchronizer is locked by
927
* the thread, this method will return a zero-length array.
928
*
929
* @return an array of {@code LockInfo} objects representing
930
* the ownable synchronizers locked by the thread.
931
*
932
* @since 1.6
933
*/
934
public LockInfo[] getLockedSynchronizers() {
935
return lockedSynchronizers.clone();
936
}
937
938
private static final StackTraceElement[] NO_STACK_TRACE =
939
new StackTraceElement[0];
940
}
941
942