aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/java/lang/management/ThreadInfo.java
diff options
context:
space:
mode:
authorMark Wielaard <mark@gcc.gnu.org>2006-08-14 23:12:35 +0000
committerMark Wielaard <mark@gcc.gnu.org>2006-08-14 23:12:35 +0000
commitac1ed908de999523efc36f38e69bca1aadfe0808 (patch)
tree97037d2c09c8384d80531f67ec36a01205df6bdb /libjava/classpath/java/lang/management/ThreadInfo.java
parentabab460491408e05ea93fb85e1975296a87df504 (diff)
downloadgcc-ac1ed908de999523efc36f38e69bca1aadfe0808.zip
gcc-ac1ed908de999523efc36f38e69bca1aadfe0808.tar.gz
gcc-ac1ed908de999523efc36f38e69bca1aadfe0808.tar.bz2
Imported GNU Classpath 0.92
2006-08-14 Mark Wielaard <mark@klomp.org> Imported GNU Classpath 0.92 * HACKING: Add more importing hints. Update automake version requirement. * configure.ac (gconf-peer): New enable AC argument. Add --disable-gconf-peer and --enable-default-preferences-peer to classpath configure when gconf is disabled. * scripts/makemake.tcl: Set gnu/java/util/prefs/gconf and gnu/java/awt/dnd/peer/gtk to bc. Classify gnu/java/security/Configuration.java as generated source file. * gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java, gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java, gnu/java/lang/management/VMClassLoadingMXBeanImpl.java, gnu/java/lang/management/VMRuntimeMXBeanImpl.java, gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java, gnu/java/lang/management/VMThreadMXBeanImpl.java, gnu/java/lang/management/VMMemoryMXBeanImpl.java, gnu/java/lang/management/VMCompilationMXBeanImpl.java: New VM stub classes. * java/lang/management/VMManagementFactory.java: Likewise. * java/net/VMURLConnection.java: Likewise. * gnu/java/nio/VMChannel.java: Likewise. * java/lang/Thread.java (getState): Add stub implementation. * java/lang/Class.java (isEnum): Likewise. * java/lang/Class.h (isEnum): Likewise. * gnu/awt/xlib/XToolkit.java (getClasspathTextLayoutPeer): Removed. * javax/naming/spi/NamingManager.java: New override for StackWalker functionality. * configure, sources.am, Makefile.in, gcj/Makefile.in, include/Makefile.in, testsuite/Makefile.in: Regenerated. From-SVN: r116139
Diffstat (limited to 'libjava/classpath/java/lang/management/ThreadInfo.java')
-rw-r--r--libjava/classpath/java/lang/management/ThreadInfo.java704
1 files changed, 704 insertions, 0 deletions
diff --git a/libjava/classpath/java/lang/management/ThreadInfo.java b/libjava/classpath/java/lang/management/ThreadInfo.java
new file mode 100644
index 0000000..4bf35a4
--- /dev/null
+++ b/libjava/classpath/java/lang/management/ThreadInfo.java
@@ -0,0 +1,704 @@
+/* ThreadInfo.java - Information on a thread
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang.management;
+
+import javax.management.openmbean.ArrayType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+
+/**
+ * <p>
+ * A class which maintains information about a particular
+ * thread. This information includes:
+ * </p>
+ * <ul>
+ * <li><strong>General Thread Information:</strong>
+ * <ul>
+ * <li>The identifier of the thread.</li>
+ * <li>The name of the thread.</li>
+ * </ul>
+ * </li>
+ * <li><strong>Execution Information:</strong>
+ * <ul>
+ * <li>The current state of the thread (e.g. blocked, runnable)</li>
+ * <li>The object upon which the thread is blocked, either because
+ * the thread is waiting to obtain the monitor of that object to enter
+ * one of its synchronized monitor, or because
+ * {@link java.lang.Object#wait()} has been called while the thread
+ * was within a method of that object.</li>
+ * <li>The thread identifier of the current thread holding an object's
+ * monitor, upon which the thread described here is blocked.</li>
+ * <li>The stack trace of the thread (if requested on creation
+ * of this object</li>
+ * </ul>
+ * <li><strong>Synchronization Statistics</strong>
+ * <ul>
+ * <li>The number of times the thread has been blocked waiting for
+ * an object's monitor or in a {@link java.lang.Object#wait()} call.</li>
+ * <li>The accumulated time the thread has been blocked waiting for
+ * an object's monitor on in a {@link java.lang.Object#wait()} call.
+ * The availability of these statistics depends on the virtual machine's
+ * support for thread contention monitoring (see
+ * {@link ThreadMXBean#isThreadContentionMonitoringSupported()}.</li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ * @see ThreadMXBean#isThreadContentionMonitoringSupported()
+ */
+public class ThreadInfo
+{
+
+ /**
+ * The id of the thread which this instance concerns.
+ */
+ private long threadId;
+
+ /**
+ * The name of the thread which this instance concerns.
+ */
+ private String threadName;
+
+ /**
+ * The state of the thread which this instance concerns.
+ */
+ private String threadState;
+
+ /**
+ * The number of times the thread has been blocked.
+ */
+ private long blockedCount;
+
+ /**
+ * The accumulated number of milliseconds the thread has
+ * been blocked (used only with thread contention monitoring
+ * support).
+ */
+ private long blockedTime;
+
+ /**
+ * The name of the monitor lock on which this thread
+ * is blocked (if any).
+ */
+ private String lockName;
+
+ /**
+ * The id of the thread which owns the monitor lock on
+ * which this thread is blocked, or <code>-1</code>
+ * if there is no owner.
+ */
+ private long lockOwnerId;
+
+ /**
+ * The name of the thread which owns the monitor lock on
+ * which this thread is blocked, or <code>null</code>
+ * if there is no owner.
+ */
+ private String lockOwnerName;
+
+ /**
+ * The number of times the thread has been in a waiting
+ * state.
+ */
+ private long waitedCount;
+
+ /**
+ * The accumulated number of milliseconds the thread has
+ * been waiting (used only with thread contention monitoring
+ * support).
+ */
+ private long waitedTime;
+
+ /**
+ * True if the thread is in a native method.
+ */
+ private boolean isInNative;
+
+ /**
+ * True if the thread is suspended.
+ */
+ private boolean isSuspended;
+
+ /**
+ * The stack trace of the thread.
+ */
+ private StackTraceElement[] trace;
+
+ /**
+ * Cache a local reference to the thread management bean.
+ */
+ private static ThreadMXBean bean = null;
+
+ /**
+ * Constructs a new {@link ThreadInfo} corresponding
+ * to the thread specified.
+ *
+ * @param thread the thread on which the new instance
+ * will be based.
+ * @param blockedCount the number of times the thread
+ * has been blocked.
+ * @param blockedTime the accumulated number of milliseconds
+ * the specified thread has been blocked
+ * (only used with contention monitoring enabled)
+ * @param lock the monitor lock the thread is waiting for
+ * (only used if blocked)
+ * @param lockOwner the thread which owns the monitor lock, or
+ * <code>null</code> if it doesn't have an owner
+ * (only used if blocked)
+ * @param waitedCount the number of times the thread has been in a
+ * waiting state.
+ * @param waitedTime the accumulated number of milliseconds the
+ * specified thread has been waiting
+ * (only used with contention monitoring enabled)
+ * @param isInNative true if the thread is in a native method.
+ * @param isSuspended true if the thread is suspended.
+ * @param trace the stack trace of the thread to a pre-determined
+ * depth (see VMThreadMXBeanImpl)
+ */
+ private ThreadInfo(Thread thread, long blockedCount, long blockedTime,
+ Object lock, Thread lockOwner, long waitedCount,
+ long waitedTime, boolean isInNative, boolean isSuspended,
+ StackTraceElement[] trace)
+ {
+ this(thread.getId(), thread.getName(), thread.getState(), blockedCount,
+ blockedTime, lock.getClass().getName() + "@" +
+ Integer.toHexString(System.identityHashCode(lock)), lockOwner.getId(),
+ lockOwner.getName(), waitedCount, waitedTime, isInNative, isSuspended,
+ trace);
+ }
+
+ /**
+ * Constructs a new {@link ThreadInfo} corresponding
+ * to the thread details specified.
+ *
+ * @param threadId the id of the thread on which this
+ * new instance will be based.
+ * @param threadName the name of the thread on which
+ * this new instance will be based.
+ * @param threadState the state of the thread on which
+ * this new instance will be based.
+ * @param blockedCount the number of times the thread
+ * has been blocked.
+ * @param blockedTime the accumulated number of milliseconds
+ * the specified thread has been blocked
+ * (only used with contention monitoring enabled)
+ * @param lockName the name of the monitor lock the thread is waiting for
+ * (only used if blocked)
+ * @param lockOwnerId the id of the thread which owns the monitor
+ * lock, or <code>-1</code> if it doesn't have an owner
+ * (only used if blocked)
+ * @param lockOwnerName the name of the thread which owns the monitor
+ * lock, or <code>null</code> if it doesn't have an
+ * owner (only used if blocked)
+ * @param waitedCount the number of times the thread has been in a
+ * waiting state.
+ * @param waitedTime the accumulated number of milliseconds the
+ * specified thread has been waiting
+ * (only used with contention monitoring enabled)
+ * @param isInNative true if the thread is in a native method.
+ * @param isSuspended true if the thread is suspended.
+ * @param trace the stack trace of the thread to a pre-determined
+ * depth (see VMThreadMXBeanImpl)
+ */
+ private ThreadInfo(long threadId, String threadName, String threadState,
+ long blockedCount, long blockedTime, String lockName,
+ long lockOwnerId, String lockOwnerName, long waitedCount,
+ long waitedTime, boolean isInNative, boolean isSuspended,
+ StackTraceElement[] trace)
+ {
+ this.threadId = threadId;
+ this.threadName = threadName;
+ this.threadState = threadState;
+ this.blockedCount = blockedCount;
+ this.blockedTime = blockedTime;
+ this.lockName = lockName;
+ this.lockOwnerId = lockOwnerId;
+ this.lockOwnerName = lockOwnerName;
+ this.waitedCount = waitedCount;
+ this.waitedTime = waitedTime;
+ this.isInNative = isInNative;
+ this.isSuspended = isSuspended;
+ this.trace = trace;
+ }
+
+ /**
+ * Checks for an attribute in a {@link CompositeData} structure
+ * with the correct type.
+ *
+ * @param ctype the composite data type to check.
+ * @param name the name of the attribute.
+ * @param type the type to check for.
+ * @throws IllegalArgumentException if the attribute is absent
+ * or of the wrong type.
+ */
+ static void checkAttribute(CompositeType ctype, String name,
+ OpenType type)
+ throws IllegalArgumentException
+ {
+ OpenType foundType = ctype.getType(name);
+ if (foundType == null)
+ throw new IllegalArgumentException("Could not find a field named " +
+ name);
+ if (!(foundType.equals(type)))
+ throw new IllegalArgumentException("Field " + name + " is not of " +
+ "type " + type.getClassName());
+ }
+
+ /**
+ * <p>
+ * Returns a {@link ThreadInfo} instance using the values
+ * given in the supplied
+ * {@link javax.management.openmbean.CompositeData} object.
+ * The composite data instance should contain the following
+ * attributes with the specified types:
+ * </p>
+ * <table>
+ * <th><td>Name</td><td>Type</td></th>
+ * <tr><td>threadId</td><td>java.lang.Long</td></tr>
+ * <tr><td>threadName</td><td>java.lang.String</td></tr>
+ * <tr><td>threadState</td><td>java.lang.String</td></tr>
+ * <tr><td>suspended</td><td>java.lang.Boolean</td></tr>
+ * <tr><td>inNative</td><td>java.lang.Boolean</td></tr>
+ * <tr><td>blockedCount</td><td>java.lang.Long</td></tr>
+ * <tr><td>blockedTime</td><td>java.lang.Long</td></tr>
+ * <tr><td>waitedCount</td><td>java.lang.Long</td></tr>
+ * <tr><td>waitedTime</td><td>java.lang.Long</td></tr>
+ * <tr><td>lockName</td><td>java.lang.String</td></tr>
+ * <tr><td>lockOwnerId</td><td>java.lang.Long</td></tr>
+ * <tr><td>lockOwnerName</td><td>java.lang.String</td></tr>
+ * <tr><td>stackTrace</td><td>javax.management.openmbean.CompositeData[]
+ * </td></tr>
+ * </table>
+ * <p>
+ * The stack trace is further described as:
+ * </p>
+ * <table>
+ * <th><td>Name</td><td>Type</td></th>
+ * <tr><td>className</td><td>java.lang.String</td></tr>
+ * <tr><td>methodName</td><td>java.lang.String</td></tr>
+ * <tr><td>fileName</td><td>java.lang.String</td></tr>
+ * <tr><td>lineNumber</td><td>java.lang.Integer</td></tr>
+ * <tr><td>nativeMethod</td><td>java.lang.Boolean</td></tr>
+ * </table>
+ *
+ * @param data the composite data structure to take values from.
+ * @return a new instance containing the values from the
+ * composite data structure, or <code>null</code>
+ * if the data structure was also <code>null</code>.
+ * @throws IllegalArgumentException if the composite data structure
+ * does not match the structure
+ * outlined above.
+ */
+ public static ThreadInfo from(CompositeData data)
+ {
+ if (data == null)
+ return null;
+ CompositeType type = data.getCompositeType();
+ checkAttribute(type, "threadId", SimpleType.LONG);
+ checkAttribute(type, "threadName", SimpleType.STRING);
+ checkAttribute(type, "threadState", SimpleType.STRING);
+ checkAttribute(type, "suspended", SimpleType.BOOLEAN);
+ checkAttribute(type, "inNative", SimpleType.BOOLEAN);
+ checkAttribute(type, "blockedCount", SimpleType.LONG);
+ checkAttribute(type, "blockedTime", SimpleType.LONG);
+ checkAttribute(type, "waitedCount", SimpleType.LONG);
+ checkAttribute(type, "waitedTime", SimpleType.LONG);
+ checkAttribute(type, "lockName", SimpleType.STRING);
+ checkAttribute(type, "lockOwnerId", SimpleType.LONG);
+ checkAttribute(type, "lockOwnerName", SimpleType.STRING);
+ try
+ {
+ CompositeType seType =
+ new CompositeType(StackTraceElement.class.getName(),
+ "An element of a stack trace",
+ new String[] { "className", "methodName",
+ "fileName", "lineNumber",
+ "nativeMethod"
+ },
+ new String[] { "Name of the class",
+ "Name of the method",
+ "Name of the source code file",
+ "Line number",
+ "True if this is a native method"
+ },
+ new OpenType[] {
+ SimpleType.STRING, SimpleType.STRING,
+ SimpleType.STRING, SimpleType.INTEGER,
+ SimpleType.BOOLEAN
+ });
+ checkAttribute(type, "stackTrace", new ArrayType(1, seType));
+ }
+ catch (OpenDataException e)
+ {
+ throw new IllegalStateException("Something went wrong in creating " +
+ "the composite data type for the " +
+ "stack trace element.", e);
+ }
+ CompositeData[] dTraces = (CompositeData[]) data.get("stackTrace");
+ StackTraceElement[] traces = new StackTraceElement[dTraces.length];
+ for (int a = 0; a < dTraces.length; ++a)
+ /* FIXME: We can't use the boolean as there is no available
+ constructor. */
+ traces[a] =
+ new StackTraceElement((String) dTraces[a].get("className"),
+ (String) dTraces[a].get("methodName"),
+ (String) dTraces[a].get("fileName"),
+ ((Integer)
+ dTraces[a].get("lineNumber")).intValue());
+ return new ThreadInfo(((Long) data.get("threadId")).longValue(),
+ (String) data.get("threadName"),
+ (String) data.get("threadState"),
+ ((Long) data.get("blockedCount")).longValue(),
+ ((Long) data.get("blockedTime")).longValue(),
+ (String) data.get("lockName"),
+ ((Long) data.get("lockOwnerId")).longValue(),
+ (String) data.get("lockOwnerName"),
+ ((Long) data.get("waitedCount")).longValue(),
+ ((Long) data.get("waitedTime")).longValue(),
+ ((Boolean) data.get("inNative")).booleanValue(),
+ ((Boolean) data.get("suspended")).booleanValue(),
+ traces);
+ }
+
+ /**
+ * Returns the number of times this thread has been
+ * in the {@link java.lang.Thread.State#BLOCKED} state.
+ * A thread enters this state when it is waiting to
+ * obtain an object's monitor. This may occur either
+ * on entering a synchronized method for the first time,
+ * or on re-entering it following a call to
+ * {@link java.lang.Object#wait()}.
+ *
+ * @return the number of times this thread has been blocked.
+ */
+ public long getBlockedCount()
+ {
+ return blockedCount;
+ }
+
+ /**
+ * <p>
+ * Returns the accumulated number of milliseconds this
+ * thread has been in the
+ * {@link java.lang.Thread.State#BLOCKED} state
+ * since thread contention monitoring was last enabled.
+ * A thread enters this state when it is waiting to
+ * obtain an object's monitor. This may occur either
+ * on entering a synchronized method for the first time,
+ * or on re-entering it following a call to
+ * {@link java.lang.Object#wait()}.
+ * </p>
+ * <p>
+ * Use of this method requires virtual machine support
+ * for thread contention monitoring and for this support
+ * to be enabled.
+ * </p>
+ *
+ * @return the accumulated time (in milliseconds) that this
+ * thread has spent in the blocked state, since
+ * thread contention monitoring was enabled, or -1
+ * if thread contention monitoring is disabled.
+ * @throws UnsupportedOperationException if the virtual
+ * machine does not
+ * support contention
+ * monitoring.
+ * @see ThreadMXBean#isThreadContentionMonitoringEnabled()
+ * @see ThreadMXBean#isThreadContentionMonitoringSupported()
+ */
+ public long getBlockedTime()
+ {
+ if (bean == null)
+ bean = ManagementFactory.getThreadMXBean();
+ // Will throw UnsupportedOperationException for us
+ if (bean.isThreadContentionMonitoringEnabled())
+ return blockedTime;
+ else
+ return -1;
+ }
+
+ /**
+ * <p>
+ * Returns a {@link java.lang.String} representation of
+ * the monitor lock on which this thread is blocked. If
+ * the thread is not blocked, this method returns
+ * <code>null</code>.
+ * </p>
+ * <p>
+ * The returned {@link java.lang.String} is constructed
+ * using the class name and identity hashcode (usually
+ * the memory address of the object) of the lock. The
+ * two are separated by the '@' character, and the identity
+ * hashcode is represented in hexadecimal. Thus, for a
+ * lock, <code>l</code>, the returned value is
+ * the result of concatenating
+ * <code>l.getClass().getName()</code>, <code>"@"</code>
+ * and
+ * <code>Integer.toHexString(System.identityHashCode(l))</code>.
+ * The value is only unique to the extent that the identity
+ * hash code is also unique.
+ * </p>
+ *
+ * @return a string representing the lock on which this
+ * thread is blocked, or <code>null</code> if
+ * the thread is not blocked.
+ */
+ public String getLockName()
+ {
+ if (threadState.equals("BLOCKED"))
+ return null;
+ return lockName;
+ }
+
+ /**
+ * Returns the identifier of the thread which owns the
+ * monitor lock this thread is waiting for. -1 is returned
+ * if either this thread is not blocked, or the lock is
+ * not held by any other thread.
+ *
+ * @return the thread identifier of thread holding the lock
+ * this thread is waiting for, or -1 if the thread
+ * is not blocked or the lock is not held by another
+ * thread.
+ */
+ public long getLockOwnerId()
+ {
+ if (threadState.equals("BLOCKED"))
+ return -1;
+ return lockOwnerId;
+ }
+
+ /**
+ * Returns the name of the thread which owns the
+ * monitor lock this thread is waiting for. <code>null</code>
+ * is returned if either this thread is not blocked,
+ * or the lock is not held by any other thread.
+ *
+ * @return the thread identifier of thread holding the lock
+ * this thread is waiting for, or <code>null</code>
+ * if the thread is not blocked or the lock is not
+ * held by another thread.
+ */
+ public String getLockOwnerName()
+ {
+ if (threadState.equals("BLOCKED"))
+ return null;
+ return lockOwnerName;
+ }
+
+ /**
+ * <p>
+ * Returns the stack trace of this thread to the depth
+ * specified on creation of this {@link ThreadInfo}
+ * object. If the depth is zero, an empty array will
+ * be returned. For non-zero arrays, the elements
+ * start with the most recent trace at position zero.
+ * The bottom of the stack represents the oldest method
+ * invocation which meets the depth requirements.
+ * </p>
+ * <p>
+ * Some virtual machines may not be able to return
+ * stack trace information for a thread. In these
+ * cases, an empty array will also be returned.
+ * </p>
+ *
+ * @return an array of {@link java.lang.StackTraceElement}s
+ * representing the trace of this thread.
+ */
+ public StackTraceElement[] getStackTrace()
+ {
+ return trace;
+ }
+
+ /**
+ * Returns the identifier of the thread associated with
+ * this instance of {@link ThreadInfo}.
+ *
+ * @return the thread's identifier.
+ */
+ public long getThreadId()
+ {
+ return threadId;
+ }
+
+ /**
+ * Returns the name of the thread associated with
+ * this instance of {@link ThreadInfo}.
+ *
+ * @return the thread's name.
+ */
+ public String getThreadName()
+ {
+ return threadName;
+ }
+
+ /**
+ * Returns the state of the thread associated with
+ * this instance of {@link ThreadInfo}.
+ *
+ * @return the thread's state.
+ */
+ public String getThreadState()
+ {
+ return threadState;
+ }
+
+ /**
+ * Returns the number of times this thread has been
+ * in the {@link java.lang.Thread.State#WAITING}
+ * or {@link java.lang.Thread.State#TIMED_WAITING} state.
+ * A thread enters one of these states when it is waiting
+ * due to a call to {@link java.lang.Object.wait()},
+ * {@link java.lang.Object.join()} or
+ * {@link java.lang.concurrent.locks.LockSupport.park()},
+ * either with an infinite or timed delay, respectively.
+ *
+ * @return the number of times this thread has been waiting.
+ */
+ public long getWaitedCount()
+ {
+ return waitedCount;
+ }
+
+ /**
+ * <p>
+ * Returns the accumulated number of milliseconds this
+ * thread has been in the
+ * {@link java.lang.Thread.State#WAITING} or
+ * {@link java.lang.Thread.State#TIMED_WAITING} state,
+ * since thread contention monitoring was last enabled.
+ * A thread enters one of these states when it is waiting
+ * due to a call to {@link java.lang.Object.wait()},
+ * {@link java.lang.Object.join()} or
+ * {@link java.lang.concurrent.locks.LockSupport.park()},
+ * either with an infinite or timed delay, respectively.
+ * </p>
+ * <p>
+ * Use of this method requires virtual machine support
+ * for thread contention monitoring and for this support
+ * to be enabled.
+ * </p>
+ *
+ * @return the accumulated time (in milliseconds) that this
+ * thread has spent in one of the waiting states, since
+ * thread contention monitoring was enabled, or -1
+ * if thread contention monitoring is disabled.
+ * @throws UnsupportedOperationException if the virtual
+ * machine does not
+ * support contention
+ * monitoring.
+ * @see ThreadMXBean#isThreadContentionMonitoringEnabled()
+ * @see ThreadMXBean#isThreadContentionMonitoringSupported()
+ */
+ public long getWaitedTime()
+ {
+ if (bean == null)
+ bean = ManagementFactory.getThreadMXBean();
+ // Will throw UnsupportedOperationException for us
+ if (bean.isThreadContentionMonitoringEnabled())
+ return waitedTime;
+ else
+ return -1;
+ }
+
+ /**
+ * Returns true if the thread is in a native method. This
+ * excludes native code which forms part of the virtual
+ * machine itself, or which results from Just-In-Time
+ * compilation.
+ *
+ * @return true if the thread is in a native method, false
+ * otherwise.
+ */
+ public boolean isInNative()
+ {
+ return isInNative;
+ }
+
+ /**
+ * Returns true if the thread has been suspended using
+ * {@link java.lang.Thread#suspend()}.
+ *
+ * @return true if the thread is suspended, false otherwise.
+ */
+ public boolean isSuspended()
+ {
+ return isSuspended;
+ }
+
+ /**
+ * Returns a {@link java.lang.String} representation of
+ * this {@link ThreadInfo} object. This takes the form
+ * <code>java.lang.management.ThreadInfo[id=tid, name=n,
+ * state=s, blockedCount=bc, waitedCount=wc, isInNative=iin,
+ * isSuspended=is]</code>, where <code>tid</code> is
+ * the thread identifier, <code>n</code> is the
+ * thread name, <code>s</code> is the thread state,
+ * <code>bc</code> is the blocked state count,
+ * <code>wc</code> is the waiting state count and
+ * <code>iin</code> and <code>is</code> are boolean
+ * flags to indicate the thread is in native code or
+ * suspended respectively. If the thread is blocked,
+ * <code>lock=l, lockOwner=lo</code> is also included,
+ * where <code>l</code> is the lock waited for, and
+ * <code>lo</code> is the thread which owns the lock
+ * (or null if there is no owner).
+ *
+ * @return the string specified above.
+ */
+ public String toString()
+ {
+ return getClass().getName() +
+ "[id=" + threadId +
+ ", name=" + threadName +
+ ", state=" + threadState +
+ ", blockedCount=" + blockedCount +
+ ", waitedCount=" + waitedCount +
+ ", isInNative=" + isInNative +
+ ", isSuspended=" + isSuspended +
+ (threadState.equals("BLOCKED") ?
+ ", lockOwnerId=" + lockOwnerId +
+ ", lockOwnerName=" + lockOwnerName : "") +
+ "]";
+ }
+
+}