OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [lang/] [management/] [ThreadInfo.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* ThreadInfo.java - Information on a thread
2
   Copyright (C) 2006 Free Software Foundation
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package java.lang.management;
39
 
40
import java.util.Arrays;
41
 
42
import javax.management.openmbean.ArrayType;
43
import javax.management.openmbean.CompositeData;
44
import javax.management.openmbean.CompositeType;
45
import javax.management.openmbean.OpenDataException;
46
import javax.management.openmbean.OpenType;
47
import javax.management.openmbean.SimpleType;
48
 
49
/**
50
 * <p>
51
 * A class which maintains information about a particular
52
 * thread.  This information includes:
53
 * </p>
54
 * <ul>
55
 * <li><strong>General Thread Information:</strong>
56
 * <ul>
57
 * <li>The identifier of the thread.</li>
58
 * <li>The name of the thread.</li>
59
 * </ul>
60
 * </li>
61
 * <li><strong>Execution Information:</strong>
62
 * <ul>
63
 * <li>The current state of the thread (e.g. blocked, runnable)</li>
64
 * <li>The object upon which the thread is blocked, either because
65
 * the thread is waiting to obtain the monitor of that object to enter
66
 * one of its synchronized monitor, or because
67
 * {@link java.lang.Object#wait()} has been called while the thread
68
 * was within a method of that object.</li>
69
 * <li>The thread identifier of the current thread holding an object's
70
 * monitor, upon which the thread described here is blocked.</li>
71
 * <li>The stack trace of the thread (if requested on creation
72
 * of this object</li>
73
 * <li>The current locks held on object monitors by the thread.</li>
74
 * <li>The current locks held on ownable synchronizers by the thread.</li>
75
 * </ul>
76
 * <li><strong>Synchronization Statistics</strong>
77
 * <ul>
78
 * <li>The number of times the thread has been blocked waiting for
79
 * an object's monitor or in a {@link java.lang.Object#wait()} call.</li>
80
 * <li>The accumulated time the thread has been blocked waiting for
81
 * an object's monitor on in a {@link java.lang.Object#wait()} call.
82
 * The availability of these statistics depends on the virtual machine's
83
 * support for thread contention monitoring (see
84
 * {@link ThreadMXBean#isThreadContentionMonitoringSupported()}.</li>
85
 * </ul>
86
 * </li>
87
 * </ul>
88
 *
89
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
90
 * @since 1.5
91
 * @see ThreadMXBean#isThreadContentionMonitoringSupported()
92
 */
93
public class ThreadInfo
94
{
95
 
96
  /**
97
   * The id of the thread which this instance concerns.
98
   */
99
  private long threadId;
100
 
101
  /**
102
   * The name of the thread which this instance concerns.
103
   */
104
  private String threadName;
105
 
106
  /**
107
   * The state of the thread which this instance concerns.
108
   */
109
  private Thread.State threadState;
110
 
111
  /**
112
   * The number of times the thread has been blocked.
113
   */
114
  private long blockedCount;
115
 
116
  /**
117
   * The accumulated number of milliseconds the thread has
118
   * been blocked (used only with thread contention monitoring
119
   * support).
120
   */
121
  private long blockedTime;
122
 
123
  /**
124
   * The name of the monitor lock on which this thread
125
   * is blocked (if any).
126
   */
127
  private String lockName;
128
 
129
  /**
130
   * The id of the thread which owns the monitor lock on
131
   * which this thread is blocked, or <code>-1</code>
132
   * if there is no owner.
133
   */
134
  private long lockOwnerId;
135
 
136
  /**
137
   * The name of the thread which owns the monitor lock on
138
   * which this thread is blocked, or <code>null</code>
139
   * if there is no owner.
140
   */
141
  private String lockOwnerName;
142
 
143
  /**
144
   * The number of times the thread has been in a waiting
145
   * state.
146
   */
147
  private long waitedCount;
148
 
149
  /**
150
   * The accumulated number of milliseconds the thread has
151
   * been waiting (used only with thread contention monitoring
152
   * support).
153
   */
154
  private long waitedTime;
155
 
156
  /**
157
   * True if the thread is in a native method.
158
   */
159
  private boolean isInNative;
160
 
161
  /**
162
   * True if the thread is suspended.
163
   */
164
  private boolean isSuspended;
165
 
166
  /**
167
   * The stack trace of the thread.
168
   */
169
  private StackTraceElement[] trace;
170
 
171
  /**
172
   * The array of information on monitors locked by the thread.
173
   */
174
  private MonitorInfo[] lockedMonitors;
175
 
176
  /**
177
   * The array of information on ownable synchronizers locked
178
   * by the thread.
179
   */
180
  private LockInfo[] lockedSynchronizers;
181
 
182
  /**
183
   * Cache a local reference to the thread management bean.
184
   */
185
  private static ThreadMXBean bean = null;
186
 
187
  /**
188
   * Cache the {@link javax.management.openmbean.CompositeType}
189
   * for the {@link StackTraceElement}.
190
   */
191
  private static CompositeType seType;
192
 
193
  /**
194
   * Constructs a new {@link ThreadInfo} corresponding
195
   * to the thread details specified.
196
   *
197
   * @param threadId the id of the thread on which this
198
   *                 new instance will be based.
199
   * @param threadName the name of the thread on which
200
   *                 this new instance will be based.
201
   * @param threadState the state of the thread on which
202
   *                 this new instance will be based.
203
   * @param blockedCount the number of times the thread
204
   *                     has been blocked.
205
   * @param blockedTime the accumulated number of milliseconds
206
   *                    the specified thread has been blocked
207
   *                    (only used with contention monitoring enabled)
208
   * @param lockName the name of the monitor lock the thread is waiting for
209
   *                 (only used if blocked)
210
   * @param lockOwnerId the id of the thread which owns the monitor
211
   *                  lock, or <code>-1</code> if it doesn't have an owner
212
   *                  (only used if blocked)
213
   * @param lockOwnerName the name of the thread which owns the monitor
214
   *                  lock, or <code>null</code> if it doesn't have an
215
   *                  owner (only used if blocked)
216
   * @param waitedCount the number of times the thread has been in a
217
   *                    waiting state.
218
   * @param waitedTime the accumulated number of milliseconds the
219
   *                   specified thread has been waiting
220
   *                   (only used with contention monitoring enabled)
221
   * @param isInNative true if the thread is in a native method.
222
   * @param isSuspended true if the thread is suspended.
223
   * @param trace the stack trace of the thread to a pre-determined
224
   *              depth (see VMThreadMXBeanImpl)
225
   * @param lockedMonitors an array of {@link MonitorInfo} objects
226
   *                       representing locks held on object monitors
227
   *                       by the thread.
228
   * @param lockedSynchronizers an array of {@link LockInfo} objects
229
   *                            representing locks held on ownable
230
   *                            synchronizers by the thread.
231
   *
232
   * @since 1.6
233
   */
234
  private ThreadInfo(long threadId, String threadName, Thread.State threadState,
235
                     long blockedCount, long blockedTime, String lockName,
236
                     long lockOwnerId, String lockOwnerName, long waitedCount,
237
                     long waitedTime, boolean isInNative, boolean isSuspended,
238
                     StackTraceElement[] trace, MonitorInfo[] lockedMonitors,
239
                     LockInfo[] lockedSynchronizers)
240
  {
241
    this.threadId = threadId;
242
    this.threadName = threadName;
243
    this.threadState = threadState;
244
    this.blockedCount = blockedCount;
245
    this.blockedTime = blockedTime;
246
    this.lockName = lockName;
247
    this.lockOwnerId = lockOwnerId;
248
    this.lockOwnerName = lockOwnerName;
249
    this.waitedCount = waitedCount;
250
    this.waitedTime = waitedTime;
251
    this.isInNative = isInNative;
252
    this.isSuspended = isSuspended;
253
    this.trace = trace;
254
    this.lockedMonitors = lockedMonitors;
255
    this.lockedSynchronizers = lockedSynchronizers;
256
  }
257
 
258
  /**
259
   * Checks for an attribute in a {@link CompositeData} structure
260
   * with the correct type.
261
   *
262
   * @param ctype the composite data type to check.
263
   * @param name the name of the attribute.
264
   * @param type the type to check for.
265
   * @throws IllegalArgumentException if the attribute is absent
266
   *                                  or of the wrong type.
267
   */
268
  static void checkAttribute(CompositeType ctype, String name,
269
                             OpenType type)
270
    throws IllegalArgumentException
271
  {
272
    OpenType foundType = ctype.getType(name);
273
    if (foundType == null)
274
      throw new IllegalArgumentException("Could not find a field named " +
275
                                         name);
276
    if (!(foundType.equals(type)))
277
      throw new IllegalArgumentException("Field " + name + " is not of " +
278
                                         "type " + type.getClassName());
279
  }
280
 
281
  /**
282
   * Returns the {@link javax.management.openmbean.CompositeType} for
283
   * a {@link StackTraceElement}.
284
   *
285
   * @return the type for the stack trace element.
286
   */
287
  static CompositeType getStackTraceType()
288
  {
289
    if (seType == null)
290
      try
291
        {
292
          seType = new CompositeType(StackTraceElement.class.getName(),
293
                                     "An element of a stack trace",
294
                                     new String[] { "className", "methodName",
295
                                                    "fileName", "lineNumber",
296
                                                    "nativeMethod"
297
                                     },
298
                                     new String[] { "Name of the class",
299
                                                    "Name of the method",
300
                                                    "Name of the source code file",
301
                                                    "Line number",
302
                                                    "True if this is a native method"
303
                                     },
304
                                     new OpenType[] {
305
                                       SimpleType.STRING, SimpleType.STRING,
306
                                       SimpleType.STRING, SimpleType.INTEGER,
307
                                       SimpleType.BOOLEAN
308
                                     });
309
        }
310
      catch (OpenDataException e)
311
        {
312
          throw new IllegalStateException("Something went wrong in creating " +
313
                                          "the composite data type for the " +
314
                                          "stack trace element.", e);
315
        }
316
    return seType;
317
  }
318
 
319
  /**
320
   * <p>
321
   * Returns a {@link ThreadInfo} instance using the values
322
   * given in the supplied
323
   * {@link javax.management.openmbean.CompositeData} object.
324
   * The composite data instance should contain the following
325
   * attributes with the specified types:
326
   * </p>
327
   * <table>
328
   * <th><td>Name</td><td>Type</td></th>
329
   * <tr><td>threadId</td><td>java.lang.Long</td></tr>
330
   * <tr><td>threadName</td><td>java.lang.String</td></tr>
331
   * <tr><td>threadState</td><td>java.lang.String</td></tr>
332
   * <tr><td>suspended</td><td>java.lang.Boolean</td></tr>
333
   * <tr><td>inNative</td><td>java.lang.Boolean</td></tr>
334
   * <tr><td>blockedCount</td><td>java.lang.Long</td></tr>
335
   * <tr><td>blockedTime</td><td>java.lang.Long</td></tr>
336
   * <tr><td>waitedCount</td><td>java.lang.Long</td></tr>
337
   * <tr><td>waitedTime</td><td>java.lang.Long</td></tr>
338
   * <tr><td>lockName</td><td>java.lang.String</td></tr>
339
   * <tr><td>lockOwnerId</td><td>java.lang.Long</td></tr>
340
   * <tr><td>lockOwnerName</td><td>java.lang.String</td></tr>
341
   * <tr><td>stackTrace</td><td>javax.management.openmbean.CompositeData[]
342
   * </td></tr>
343
   * </table>
344
   * <p>
345
   * The stack trace is further described as:
346
   * </p>
347
   * <table>
348
   * <th><td>Name</td><td>Type</td></th>
349
   * <tr><td>className</td><td>java.lang.String</td></tr>
350
   * <tr><td>methodName</td><td>java.lang.String</td></tr>
351
   * <tr><td>fileName</td><td>java.lang.String</td></tr>
352
   * <tr><td>lineNumber</td><td>java.lang.Integer</td></tr>
353
   * <tr><td>nativeMethod</td><td>java.lang.Boolean</td></tr>
354
   * </table>
355
   *
356
   * @param data the composite data structure to take values from.
357
   * @return a new instance containing the values from the
358
   *         composite data structure, or <code>null</code>
359
   *         if the data structure was also <code>null</code>.
360
   * @throws IllegalArgumentException if the composite data structure
361
   *                                  does not match the structure
362
   *                                  outlined above.
363
   */
364
  public static ThreadInfo from(CompositeData data)
365
  {
366
    if (data == null)
367
      return null;
368
    CompositeType type = data.getCompositeType();
369
    checkAttribute(type, "ThreadId", SimpleType.LONG);
370
    checkAttribute(type, "ThreadName", SimpleType.STRING);
371
    checkAttribute(type, "ThreadState", SimpleType.STRING);
372
    checkAttribute(type, "Suspended", SimpleType.BOOLEAN);
373
    checkAttribute(type, "InNative", SimpleType.BOOLEAN);
374
    checkAttribute(type, "BlockedCount", SimpleType.LONG);
375
    checkAttribute(type, "BlockedTime", SimpleType.LONG);
376
    checkAttribute(type, "WaitedCount", SimpleType.LONG);
377
    checkAttribute(type, "WaitedTime", SimpleType.LONG);
378
    checkAttribute(type, "LockName", SimpleType.STRING);
379
    checkAttribute(type, "LockOwnerId", SimpleType.LONG);
380
    checkAttribute(type, "LockOwnerName", SimpleType.STRING);
381
    try
382
      {
383
        checkAttribute(type, "StackTrace",
384
                       new ArrayType(1, getStackTraceType()));
385
      }
386
    catch (OpenDataException e)
387
      {
388
        throw new IllegalStateException("Something went wrong in creating " +
389
                                        "the array for the stack trace element.",
390
                                        e);
391
      }
392
    OpenType foundType = type.getType("LockedMonitors");
393
    if (foundType != null)
394
      try
395
        {
396
          CompositeType mType = new CompositeType(MonitorInfo.class.getName(),
397
                                                  "Information on a object monitor lock",
398
                                                  new String[] { "ClassName",
399
                                                                 "IdentityHashCode",
400
                                                                 "LockedStackDepth",
401
                                                                 "LockedStackFrame"
402
                                                  },
403
                                                  new String[] { "Name of the class",
404
                                                                 "Identity hash code " +
405
                                                                 "of the class",
406
                                                                 "Stack depth at time " +
407
                                                                 "of lock",
408
                                                                 "Stack frame at time " +
409
                                                                 "of lock",
410
                                                  },
411
                                                  new OpenType[] {
412
                                                    SimpleType.STRING, SimpleType.INTEGER,
413
                                                    SimpleType.INTEGER, getStackTraceType()
414
                                                  });
415
          if (!(foundType.equals(new ArrayType(1, mType))))
416
            throw new IllegalArgumentException("Field LockedMonitors is not of " +
417
                                               "type " + mType.getClassName());
418
        }
419
    catch (OpenDataException e)
420
      {
421
        throw new IllegalStateException("Something went wrong in creating " +
422
                                        "the composite data type for the " +
423
                                        "object monitor information array.", e);
424
      }
425
    foundType = type.getType("LockedSynchronizers");
426
    if (foundType != null)
427
      try
428
        {
429
          CompositeType lType = new CompositeType(LockInfo.class.getName(),
430
                                                  "Information on a lock",
431
                                                  new String[] { "ClassName",
432
                                                                 "IdentityHashCode"
433
                                                  },
434
                                                  new String[] { "Name of the class",
435
                                                                 "Identity hash code " +
436
                                                                 "of the class"
437
                                                  },
438
                                                  new OpenType[] {
439
                                                    SimpleType.STRING, SimpleType.INTEGER
440
                                                  });
441
          if (!(foundType.equals(new ArrayType(1, lType))))
442
            throw new IllegalArgumentException("Field LockedSynchronizers is not of " +
443
                                               "type " + lType.getClassName());
444
        }
445
    catch (OpenDataException e)
446
      {
447
        throw new IllegalStateException("Something went wrong in creating " +
448
                                        "the composite data type for the " +
449
                                        "ownable synchronizerinformation array.", e);
450
      }
451
    CompositeData[] dTraces = (CompositeData[]) data.get("StackTrace");
452
    StackTraceElement[] traces = new StackTraceElement[dTraces.length];
453
    for (int a = 0; a < dTraces.length; ++a)
454
        /* FIXME: We can't use the boolean as there is no available
455
           constructor. */
456
      traces[a] =
457
        new StackTraceElement((String) dTraces[a].get("ClassName"),
458
                              (String) dTraces[a].get("MethodName"),
459
                              (String) dTraces[a].get("FileName"),
460
                              ((Integer)
461
                               dTraces[a].get("LineNumber")).intValue());
462
    MonitorInfo[] mInfo;
463
    if (data.containsKey("LockedMonitors"))
464
      {
465
        CompositeData[] dmInfos = (CompositeData[]) data.get("LockedMonitors");
466
        mInfo = new MonitorInfo[dmInfos.length];
467
        for (int a = 0; a < dmInfos.length; ++a)
468
          mInfo[a] = MonitorInfo.from(dmInfos[a]);
469
      }
470
    else
471
      mInfo = new MonitorInfo[]{};
472
    LockInfo[] lInfo;
473
    if (data.containsKey("LockedSynchronizers"))
474
      {
475
        CompositeData[] dlInfos = (CompositeData[]) data.get("LockedSynchronizers");
476
        lInfo = new LockInfo[dlInfos.length];
477
        for (int a = 0; a < dlInfos.length; ++a)
478
          lInfo[a] = new LockInfo((String) dlInfos[a].get("ClassName"),
479
                                  (Integer) dlInfos[a].get("IdentityHashCode"));
480
      }
481
    else
482
      lInfo = new LockInfo[]{};
483
    return new ThreadInfo(((Long) data.get("ThreadId")).longValue(),
484
                          (String) data.get("ThreadName"),
485
                          Thread.State.valueOf((String) data.get("ThreadState")),
486
                          ((Long) data.get("BlockedCount")).longValue(),
487
                          ((Long) data.get("BlockedTime")).longValue(),
488
                          (String) data.get("LockName"),
489
                          ((Long) data.get("LockOwnerId")).longValue(),
490
                          (String) data.get("LockOwnerName"),
491
                          ((Long) data.get("WaitedCount")).longValue(),
492
                          ((Long) data.get("WaitedTime")).longValue(),
493
                          ((Boolean) data.get("InNative")).booleanValue(),
494
                          ((Boolean) data.get("Suspended")).booleanValue(),
495
                          traces, mInfo, lInfo);
496
  }
497
 
498
  /**
499
   * Returns the number of times this thread has been
500
   * in the {@link java.lang.Thread.State#BLOCKED} state.
501
   * A thread enters this state when it is waiting to
502
   * obtain an object's monitor.  This may occur either
503
   * on entering a synchronized method for the first time,
504
   * or on re-entering it following a call to
505
   * {@link java.lang.Object#wait()}.
506
   *
507
   * @return the number of times this thread has been blocked.
508
   */
509
  public long getBlockedCount()
510
  {
511
    return blockedCount;
512
  }
513
 
514
  /**
515
   * <p>
516
   * Returns the accumulated number of milliseconds this
517
   * thread has been in the
518
   * {@link java.lang.Thread.State#BLOCKED} state
519
   * since thread contention monitoring was last enabled.
520
   * A thread enters this state when it is waiting to
521
   * obtain an object's monitor.  This may occur either
522
   * on entering a synchronized method for the first time,
523
   * or on re-entering it following a call to
524
   * {@link java.lang.Object#wait()}.
525
   * </p>
526
   * <p>
527
   * Use of this method requires virtual machine support
528
   * for thread contention monitoring and for this support
529
   * to be enabled.
530
   * </p>
531
   *
532
   * @return the accumulated time (in milliseconds) that this
533
   *         thread has spent in the blocked state, since
534
   *         thread contention monitoring was enabled, or -1
535
   *         if thread contention monitoring is disabled.
536
   * @throws UnsupportedOperationException if the virtual
537
   *                                       machine does not
538
   *                                       support contention
539
   *                                       monitoring.
540
   * @see ThreadMXBean#isThreadContentionMonitoringEnabled()
541
   * @see ThreadMXBean#isThreadContentionMonitoringSupported()
542
   */
543
  public long getBlockedTime()
544
  {
545
    if (bean == null)
546
      bean = ManagementFactory.getThreadMXBean();
547
    // Will throw UnsupportedOperationException for us
548
    if (bean.isThreadContentionMonitoringEnabled())
549
      return blockedTime;
550
    else
551
      return -1;
552
  }
553
 
554
  /**
555
   * Returns an array of {@link MonitorInfo} objects representing
556
   * information on the locks on object monitors held by the thread.
557
   * If no locks are held, or such information was not requested
558
   * on creating this {@link ThreadInfo} object, a zero-length
559
   * array will be returned.
560
   *
561
   * @return information on object monitors locked by this thread.
562
   */
563
  public MonitorInfo[] getLockedMonitors()
564
  {
565
    return lockedMonitors;
566
  }
567
 
568
  /**
569
   * Returns an array of {@link LockInfo} objects representing
570
   * information on the locks on ownable synchronizers held by the thread.
571
   * If no locks are held, or such information was not requested
572
   * on creating this {@link ThreadInfo} object, a zero-length
573
   * array will be returned.
574
   *
575
   * @return information on ownable synchronizers locked by this thread.
576
   */
577
  public LockInfo[] getLockedSynchronizers()
578
  {
579
    return lockedSynchronizers;
580
  }
581
 
582
  /**
583
   * <p>
584
   * Returns a {@link LockInfo} object representing the
585
   * lock on which this thread is blocked.  If the thread
586
   * is not blocked, this method returns <code>null</code>.
587
   * </p>
588
   * <p>
589
   * The thread may be blocked due to one of three reasons:
590
   * </p>
591
   * <ol>
592
   * <li>The thread is in the <code>BLOCKED</code> state
593
   * waiting to acquire an object monitor in order to enter
594
   * a synchronized method or block.</li>
595
   * <li>The thread is in the <code>WAITING</code> or
596
   * <code>TIMED_WAITING</code> state due to a call to
597
   * {@link java.lang.Object#wait()}.</li>
598
   * <li>The thread is in the <code>WAITING</code> or
599
   * <code>TIMED_WAITING</code> state due to a call
600
   * to {@link java.util.concurrent.locks.LockSupport#park()}.
601
   * The lock is the return value of
602
   * {@link java.util.concurrent.locks.LockSupport#getBlocker()}.</li>
603
   * </ol>
604
   *
605
   * @return a {@link LockInfo} object representing the lock on
606
   *         which the thread is blocked, or <code>null</code> if
607
   *         the thread isn't blocked.
608
   * @since 1.6
609
   * @see #getLockName()
610
   */
611
  public LockInfo getLockInfo()
612
  {
613
    String lockName = getLockName();
614
    int at = lockName.indexOf('@');
615
    return new LockInfo(lockName.substring(0, at),
616
                        Integer.decode(lockName.substring(at + 1)));
617
  }
618
 
619
  /**
620
   * <p>
621
   * Returns a {@link java.lang.String} representation of
622
   * the lock on which this thread is blocked.  If
623
   * the thread is not blocked, this method returns
624
   * <code>null</code>.
625
   * </p>
626
   * <p>
627
   * The returned {@link java.lang.String} is constructed
628
   * using the class name and identity hashcode (usually
629
   * the memory address of the object) of the lock.  The
630
   * two are separated by the '@' character, and the identity
631
   * hashcode is represented in hexadecimal.  Thus, for a
632
   * lock, <code>l</code>, the returned value is
633
   * the result of concatenating
634
   * <code>l.getClass().getName()</code>, <code>"@"</code>
635
   * and
636
   * <code>Integer.toHexString(System.identityHashCode(l))</code>.
637
   * The value is only unique to the extent that the identity
638
   * hash code is also unique.  The value is the same as would
639
   * be returned by <code>getLockInfo().toString()</code>
640
   * </p>
641
   *
642
   * @return a string representing the lock on which this
643
   *         thread is blocked, or <code>null</code> if
644
   *         the thread is not blocked.
645
   */
646
  public String getLockName()
647
  {
648
    if (!isThreadBlocked())
649
      return null;
650
    return lockName;
651
  }
652
 
653
  /**
654
   * Returns the identifier of the thread which owns the
655
   * monitor lock this thread is waiting for.  -1 is returned
656
   * if either this thread is not blocked, or the lock is
657
   * not held by any other thread.
658
   *
659
   * @return the thread identifier of thread holding the lock
660
   *         this thread is waiting for, or -1 if the thread
661
   *         is not blocked or the lock is not held by another
662
   *         thread.
663
   */
664
  public long getLockOwnerId()
665
  {
666
    if (!isThreadBlocked())
667
      return -1;
668
    return lockOwnerId;
669
  }
670
 
671
  /**
672
   * Returns the name of the thread which owns the
673
   * monitor lock this thread is waiting for.  <code>null</code>
674
   * is returned if either this thread is not blocked,
675
   * or the lock is not held by any other thread.
676
   *
677
   * @return the thread identifier of thread holding the lock
678
   *         this thread is waiting for, or <code>null</code>
679
   *         if the thread is not blocked or the lock is not
680
   *         held by another thread.
681
   */
682
  public String getLockOwnerName()
683
  {
684
    if (!isThreadBlocked())
685
      return null;
686
    return lockOwnerName;
687
  }
688
 
689
  /**
690
   * <p>
691
   * Returns the stack trace of this thread to the depth
692
   * specified on creation of this {@link ThreadInfo}
693
   * object.  If the depth is zero, an empty array will
694
   * be returned.  For non-zero arrays, the elements
695
   * start with the most recent trace at position zero.
696
   * The bottom of the stack represents the oldest method
697
   * invocation which meets the depth requirements.
698
   * </p>
699
   * <p>
700
   * Some virtual machines may not be able to return
701
   * stack trace information for a thread.  In these
702
   * cases, an empty array will also be returned.
703
   * </p>
704
   *
705
   * @return an array of {@link java.lang.StackTraceElement}s
706
   *         representing the trace of this thread.
707
   */
708
  public StackTraceElement[] getStackTrace()
709
  {
710
    return trace;
711
  }
712
 
713
  /**
714
   * Returns the identifier of the thread associated with
715
   * this instance of {@link ThreadInfo}.
716
   *
717
   * @return the thread's identifier.
718
   */
719
  public long getThreadId()
720
  {
721
    return threadId;
722
  }
723
 
724
  /**
725
   * Returns the name of the thread associated with
726
   * this instance of {@link ThreadInfo}.
727
   *
728
   * @return the thread's name.
729
   */
730
  public String getThreadName()
731
  {
732
    return threadName;
733
  }
734
 
735
  /**
736
   * Returns the state of the thread associated with
737
   * this instance of {@link ThreadInfo}.
738
   *
739
   * @return the thread's state.
740
   */
741
  public Thread.State getThreadState()
742
  {
743
    return threadState;
744
  }
745
 
746
  /**
747
   * Returns the number of times this thread has been
748
   * in the {@link java.lang.Thread.State#WAITING}
749
   * or {@link java.lang.Thread.State#TIMED_WAITING} state.
750
   * A thread enters one of these states when it is waiting
751
   * due to a call to {@link java.lang.Object.wait()},
752
   * {@link java.lang.Object.join()} or
753
   * {@link java.lang.concurrent.locks.LockSupport.park()},
754
   * either with an infinite or timed delay, respectively.
755
   *
756
   * @return the number of times this thread has been waiting.
757
   */
758
  public long getWaitedCount()
759
  {
760
    return waitedCount;
761
  }
762
 
763
  /**
764
   * <p>
765
   * Returns the accumulated number of milliseconds this
766
   * thread has been in the
767
   * {@link java.lang.Thread.State#WAITING} or
768
   * {@link java.lang.Thread.State#TIMED_WAITING} state,
769
   * since thread contention monitoring was last enabled.
770
   * A thread enters one of these states when it is waiting
771
   * due to a call to {@link java.lang.Object.wait()},
772
   * {@link java.lang.Object.join()} or
773
   * {@link java.lang.concurrent.locks.LockSupport.park()},
774
   * either with an infinite or timed delay, respectively.
775
   * </p>
776
   * <p>
777
   * Use of this method requires virtual machine support
778
   * for thread contention monitoring and for this support
779
   * to be enabled.
780
   * </p>
781
   *
782
   * @return the accumulated time (in milliseconds) that this
783
   *         thread has spent in one of the waiting states, since
784
   *         thread contention monitoring was enabled, or -1
785
   *         if thread contention monitoring is disabled.
786
   * @throws UnsupportedOperationException if the virtual
787
   *                                       machine does not
788
   *                                       support contention
789
   *                                       monitoring.
790
   * @see ThreadMXBean#isThreadContentionMonitoringEnabled()
791
   * @see ThreadMXBean#isThreadContentionMonitoringSupported()
792
   */
793
  public long getWaitedTime()
794
  {
795
    if (bean == null)
796
      bean = ManagementFactory.getThreadMXBean();
797
    // Will throw UnsupportedOperationException for us
798
    if (bean.isThreadContentionMonitoringEnabled())
799
      return waitedTime;
800
    else
801
      return -1;
802
  }
803
 
804
  /**
805
   * Returns true if the thread is in a native method.  This
806
   * excludes native code which forms part of the virtual
807
   * machine itself, or which results from Just-In-Time
808
   * compilation.
809
   *
810
   * @return true if the thread is in a native method, false
811
   *         otherwise.
812
   */
813
  public boolean isInNative()
814
  {
815
    return isInNative;
816
  }
817
 
818
  /**
819
   * Returns true if the thread has been suspended using
820
   * {@link java.lang.Thread#suspend()}.
821
   *
822
   * @return true if the thread is suspended, false otherwise.
823
   */
824
  public boolean isSuspended()
825
  {
826
    return isSuspended;
827
  }
828
 
829
  /**
830
   * Returns a {@link java.lang.String} representation of
831
   * this {@link ThreadInfo} object.  This takes the form
832
   * <code>java.lang.management.ThreadInfo[id=tid, name=n,
833
   * state=s, blockedCount=bc, waitedCount=wc, isInNative=iin,
834
   * isSuspended=is]</code>, where <code>tid</code> is
835
   * the thread identifier, <code>n</code> is the
836
   * thread name, <code>s</code> is the thread state,
837
   * <code>bc</code> is the blocked state count,
838
   * <code>wc</code> is the waiting state count and
839
   * <code>iin</code> and <code>is</code> are boolean
840
   * flags to indicate the thread is in native code or
841
   * suspended respectively.  If the thread is blocked,
842
   * <code>lock=l, lockOwner=lo</code> is also included,
843
   * where <code>l</code> is the lock waited for, and
844
   * <code>lo</code> is the thread which owns the lock
845
   * (or null if there is no owner).
846
   *
847
   * @return the string specified above.
848
   */
849
  public String toString()
850
  {
851
    return getClass().getName() +
852
      "[id=" + threadId +
853
      ", name=" + threadName +
854
      ", state=" + threadState +
855
      ", blockedCount=" + blockedCount +
856
      ", waitedCount=" + waitedCount +
857
      ", isInNative=" + isInNative +
858
      ", isSuspended=" + isSuspended +
859
      (isThreadBlocked() ?
860
       ", lockOwnerId=" + lockOwnerId +
861
       ", lockOwnerName=" + lockOwnerName : "") +
862
      ", lockedMonitors=" + Arrays.toString(lockedMonitors) +
863
      ", lockedSynchronizers=" + Arrays.toString(lockedSynchronizers) +
864
      "]";
865
  }
866
 
867
  /**
868
   * <p>
869
   * Returns true if the thread is in a blocked state.
870
   * The thread is regarded as blocked if:
871
   * </p>
872
   * <ol>
873
   * <li>The thread is in the <code>BLOCKED</code> state
874
   * waiting to acquire an object monitor in order to enter
875
   * a synchronized method or block.</li>
876
   * <li>The thread is in the <code>WAITING</code> or
877
   * <code>TIMED_WAITING</code> state due to a call to
878
   * {@link java.lang.Object#wait()}.</li>
879
   * <li>The thread is in the <code>WAITING</code> or
880
   * <code>TIMED_WAITING</code> state due to a call
881
   * to {@link java.util.concurrent.locks.LockSupport#park()}.
882
   * The lock is the return value of
883
   * {@link java.util.concurrent.locks.LockSupport#getBlocker()}.</li>
884
   * </ol>
885
   *
886
   * @return true if the thread is blocked.
887
   */
888
  private boolean isThreadBlocked()
889
  {
890
    return (threadState == Thread.State.BLOCKED ||
891
            threadState == Thread.State.WAITING ||
892
            threadState == Thread.State.TIMED_WAITING);
893
  }
894
 
895
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.