diff options
author | Mark Wielaard <mark@gcc.gnu.org> | 2006-08-14 23:12:35 +0000 |
---|---|---|
committer | Mark Wielaard <mark@gcc.gnu.org> | 2006-08-14 23:12:35 +0000 |
commit | ac1ed908de999523efc36f38e69bca1aadfe0808 (patch) | |
tree | 97037d2c09c8384d80531f67ec36a01205df6bdb /libjava/classpath/java/lang/management/ThreadInfo.java | |
parent | abab460491408e05ea93fb85e1975296a87df504 (diff) | |
download | gcc-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.java | 704 |
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 : "") + + "]"; + } + +} |