6588467: Add isDaemon() and getPriority() to ThreadInfo
Reviewed-by: mchung, sla, dholmes, martin
This commit is contained in:
parent
9a2cc32b19
commit
d1225ad485
@ -31,12 +31,13 @@ import sun.management.ThreadInfoCompositeData;
|
||||
import static java.lang.Thread.State.*;
|
||||
|
||||
/**
|
||||
* Thread information. <tt>ThreadInfo</tt> contains the information
|
||||
* Thread information. {@code ThreadInfo} contains the information
|
||||
* about a thread including:
|
||||
* <h3>General thread information</h3>
|
||||
* <ul>
|
||||
* <li>Thread ID.</li>
|
||||
* <li>Name of the thread.</li>
|
||||
* <li>Whether a thread is a daemon thread</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h3>Execution information</h3>
|
||||
@ -57,6 +58,7 @@ import static java.lang.Thread.State.*;
|
||||
* <li>List of object monitors locked by the thread.</li>
|
||||
* <li>List of <a href="LockInfo.html#OwnableSynchronizer">
|
||||
* ownable synchronizers</a> locked by the thread.</li>
|
||||
* <li>Thread priority</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h4><a name="SyncStats">Synchronization Statistics</a></h4>
|
||||
@ -78,7 +80,7 @@ import static java.lang.Thread.State.*;
|
||||
* the system, not for synchronization control.
|
||||
*
|
||||
* <h4>MXBean Mapping</h4>
|
||||
* <tt>ThreadInfo</tt> is mapped to a {@link CompositeData CompositeData}
|
||||
* {@code ThreadInfo} is mapped to a {@link CompositeData CompositeData}
|
||||
* with attributes as specified in
|
||||
* the {@link #from from} method.
|
||||
*
|
||||
@ -100,9 +102,11 @@ public class ThreadInfo {
|
||||
private String lockName;
|
||||
private long lockOwnerId;
|
||||
private String lockOwnerName;
|
||||
private boolean daemon;
|
||||
private boolean inNative;
|
||||
private boolean suspended;
|
||||
private Thread.State threadState;
|
||||
private int priority;
|
||||
private StackTraceElement[] stackTrace;
|
||||
private MonitorInfo[] lockedMonitors;
|
||||
private LockInfo[] lockedSynchronizers;
|
||||
@ -229,6 +233,8 @@ public class ThreadInfo {
|
||||
this.blockedTime = blockedTime;
|
||||
this.waitedCount = waitedCount;
|
||||
this.waitedTime = waitedTime;
|
||||
this.daemon = t.isDaemon();
|
||||
this.priority = t.getPriority();
|
||||
|
||||
if (lockObj == null) {
|
||||
this.lock = null;
|
||||
@ -256,7 +262,7 @@ public class ThreadInfo {
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructs a <tt>ThreadInfo</tt> object from a
|
||||
* Constructs a {@code ThreadInfo} object from a
|
||||
* {@link CompositeData CompositeData}.
|
||||
*/
|
||||
private ThreadInfo(CompositeData cd) {
|
||||
@ -277,7 +283,7 @@ public class ThreadInfo {
|
||||
stackTrace = ticd.stackTrace();
|
||||
|
||||
// 6.0 attributes
|
||||
if (ticd.isCurrentVersion()) {
|
||||
if (ticd.hasV6()) {
|
||||
lock = ticd.lockInfo();
|
||||
lockedMonitors = ticd.lockedMonitors();
|
||||
lockedSynchronizers = ticd.lockedSynchronizers();
|
||||
@ -300,10 +306,20 @@ public class ThreadInfo {
|
||||
lockedMonitors = EMPTY_MONITORS;
|
||||
lockedSynchronizers = EMPTY_SYNCS;
|
||||
}
|
||||
|
||||
// 9.0 attributes
|
||||
if (ticd.isCurrentVersion()) {
|
||||
daemon = ticd.isDaemon();
|
||||
priority = ticd.getPriority();
|
||||
} else {
|
||||
// Not ideal, but unclear what else we can do.
|
||||
daemon = false;
|
||||
priority = Thread.NORM_PRIORITY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the thread associated with this <tt>ThreadInfo</tt>.
|
||||
* Returns the ID of the thread associated with this {@code ThreadInfo}.
|
||||
*
|
||||
* @return the ID of the associated thread.
|
||||
*/
|
||||
@ -312,7 +328,7 @@ public class ThreadInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the thread associated with this <tt>ThreadInfo</tt>.
|
||||
* Returns the name of the thread associated with this {@code ThreadInfo}.
|
||||
*
|
||||
* @return the name of the associated thread.
|
||||
*/
|
||||
@ -321,9 +337,9 @@ public class ThreadInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state of the thread associated with this <tt>ThreadInfo</tt>.
|
||||
* Returns the state of the thread associated with this {@code ThreadInfo}.
|
||||
*
|
||||
* @return <tt>Thread.State</tt> of the associated thread.
|
||||
* @return {@code Thread.State} of the associated thread.
|
||||
*/
|
||||
public Thread.State getThreadState() {
|
||||
return threadState;
|
||||
@ -331,13 +347,13 @@ public class ThreadInfo {
|
||||
|
||||
/**
|
||||
* Returns the approximate accumulated elapsed time (in milliseconds)
|
||||
* that the thread associated with this <tt>ThreadInfo</tt>
|
||||
* that the thread associated with this {@code ThreadInfo}
|
||||
* has blocked to enter or reenter a monitor
|
||||
* since thread contention monitoring is enabled.
|
||||
* I.e. the total accumulated time the thread has been in the
|
||||
* {@link java.lang.Thread.State#BLOCKED BLOCKED} state since thread
|
||||
* contention monitoring was last enabled.
|
||||
* This method returns <tt>-1</tt> if thread contention monitoring
|
||||
* This method returns {@code -1} if thread contention monitoring
|
||||
* is disabled.
|
||||
*
|
||||
* <p>The Java virtual machine may measure the time with a high
|
||||
@ -345,8 +361,8 @@ public class ThreadInfo {
|
||||
* the thread contention monitoring is reenabled.
|
||||
*
|
||||
* @return the approximate accumulated elapsed time in milliseconds
|
||||
* that a thread entered the <tt>BLOCKED</tt> state;
|
||||
* <tt>-1</tt> if thread contention monitoring is disabled.
|
||||
* that a thread entered the {@code BLOCKED} state;
|
||||
* {@code -1} if thread contention monitoring is disabled.
|
||||
*
|
||||
* @throws java.lang.UnsupportedOperationException if the Java
|
||||
* virtual machine does not support this operation.
|
||||
@ -360,13 +376,13 @@ public class ThreadInfo {
|
||||
|
||||
/**
|
||||
* Returns the total number of times that
|
||||
* the thread associated with this <tt>ThreadInfo</tt>
|
||||
* the thread associated with this {@code ThreadInfo}
|
||||
* blocked to enter or reenter a monitor.
|
||||
* I.e. the number of times a thread has been in the
|
||||
* {@link java.lang.Thread.State#BLOCKED BLOCKED} state.
|
||||
*
|
||||
* @return the total number of times that the thread
|
||||
* entered the <tt>BLOCKED</tt> state.
|
||||
* entered the {@code BLOCKED} state.
|
||||
*/
|
||||
public long getBlockedCount() {
|
||||
return blockedCount;
|
||||
@ -374,14 +390,14 @@ public class ThreadInfo {
|
||||
|
||||
/**
|
||||
* Returns the approximate accumulated elapsed time (in milliseconds)
|
||||
* that the thread associated with this <tt>ThreadInfo</tt>
|
||||
* that the thread associated with this {@code ThreadInfo}
|
||||
* has waited for notification
|
||||
* since thread contention monitoring is enabled.
|
||||
* I.e. the total accumulated time the thread has been in the
|
||||
* {@link java.lang.Thread.State#WAITING WAITING}
|
||||
* or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state
|
||||
* since thread contention monitoring is enabled.
|
||||
* This method returns <tt>-1</tt> if thread contention monitoring
|
||||
* This method returns {@code -1} if thread contention monitoring
|
||||
* is disabled.
|
||||
*
|
||||
* <p>The Java virtual machine may measure the time with a high
|
||||
@ -389,9 +405,9 @@ public class ThreadInfo {
|
||||
* the thread contention monitoring is reenabled.
|
||||
*
|
||||
* @return the approximate accumulated elapsed time in milliseconds
|
||||
* that a thread has been in the <tt>WAITING</tt> or
|
||||
* <tt>TIMED_WAITING</tt> state;
|
||||
* <tt>-1</tt> if thread contention monitoring is disabled.
|
||||
* that a thread has been in the {@code WAITING} or
|
||||
* {@code TIMED_WAITING} state;
|
||||
* {@code -1} if thread contention monitoring is disabled.
|
||||
*
|
||||
* @throws java.lang.UnsupportedOperationException if the Java
|
||||
* virtual machine does not support this operation.
|
||||
@ -405,29 +421,29 @@ public class ThreadInfo {
|
||||
|
||||
/**
|
||||
* Returns the total number of times that
|
||||
* the thread associated with this <tt>ThreadInfo</tt>
|
||||
* the thread associated with this {@code ThreadInfo}
|
||||
* waited for notification.
|
||||
* I.e. the number of times that a thread has been
|
||||
* in the {@link java.lang.Thread.State#WAITING WAITING}
|
||||
* or {@link java.lang.Thread.State#TIMED_WAITING TIMED_WAITING} state.
|
||||
*
|
||||
* @return the total number of times that the thread
|
||||
* was in the <tt>WAITING</tt> or <tt>TIMED_WAITING</tt> state.
|
||||
* was in the {@code WAITING} or {@code TIMED_WAITING} state.
|
||||
*/
|
||||
public long getWaitedCount() {
|
||||
return waitedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <tt>LockInfo</tt> of an object for which
|
||||
* the thread associated with this <tt>ThreadInfo</tt>
|
||||
* Returns the {@code LockInfo} of an object for which
|
||||
* the thread associated with this {@code ThreadInfo}
|
||||
* is blocked waiting.
|
||||
* A thread can be blocked waiting for one of the following:
|
||||
* <ul>
|
||||
* <li>an object monitor to be acquired for entering or reentering
|
||||
* a synchronization block/method.
|
||||
* <br>The thread is in the {@link java.lang.Thread.State#BLOCKED BLOCKED}
|
||||
* state waiting to enter the <tt>synchronized</tt> statement
|
||||
* state waiting to enter the {@code synchronized} statement
|
||||
* or method.
|
||||
* </li>
|
||||
* <li>an object monitor to be notified by another thread.
|
||||
@ -448,11 +464,11 @@ public class ThreadInfo {
|
||||
* or a {@link java.util.concurrent.locks.Condition Condition}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>This method returns <tt>null</tt> if the thread is not in any of
|
||||
* <p>This method returns {@code null} if the thread is not in any of
|
||||
* the above conditions.
|
||||
*
|
||||
* @return <tt>LockInfo</tt> of an object for which the thread
|
||||
* is blocked waiting if any; <tt>null</tt> otherwise.
|
||||
* @return {@code LockInfo} of an object for which the thread
|
||||
* is blocked waiting if any; {@code null} otherwise.
|
||||
* @since 1.6
|
||||
*/
|
||||
public LockInfo getLockInfo() {
|
||||
@ -462,19 +478,19 @@ public class ThreadInfo {
|
||||
/**
|
||||
* Returns the {@link LockInfo#toString string representation}
|
||||
* of an object for which the thread associated with this
|
||||
* <tt>ThreadInfo</tt> is blocked waiting.
|
||||
* {@code ThreadInfo} is blocked waiting.
|
||||
* This method is equivalent to calling:
|
||||
* <blockquote>
|
||||
* <pre>
|
||||
* getLockInfo().toString()
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* <p>This method will return <tt>null</tt> if this thread is not blocked
|
||||
* <p>This method will return {@code null} if this thread is not blocked
|
||||
* waiting for any object or if the object is not owned by any thread.
|
||||
*
|
||||
* @return the string representation of the object on which
|
||||
* the thread is blocked if any;
|
||||
* <tt>null</tt> otherwise.
|
||||
* {@code null} otherwise.
|
||||
*
|
||||
* @see #getLockInfo
|
||||
*/
|
||||
@ -484,14 +500,14 @@ public class ThreadInfo {
|
||||
|
||||
/**
|
||||
* Returns the ID of the thread which owns the object
|
||||
* for which the thread associated with this <tt>ThreadInfo</tt>
|
||||
* for which the thread associated with this {@code ThreadInfo}
|
||||
* is blocked waiting.
|
||||
* This method will return <tt>-1</tt> if this thread is not blocked
|
||||
* This method will return {@code -1} if this thread is not blocked
|
||||
* waiting for any object or if the object is not owned by any thread.
|
||||
*
|
||||
* @return the thread ID of the owner thread of the object
|
||||
* this thread is blocked on;
|
||||
* <tt>-1</tt> if this thread is not blocked
|
||||
* {@code -1} if this thread is not blocked
|
||||
* or if the object is not owned by any thread.
|
||||
*
|
||||
* @see #getLockInfo
|
||||
@ -502,14 +518,14 @@ public class ThreadInfo {
|
||||
|
||||
/**
|
||||
* Returns the name of the thread which owns the object
|
||||
* for which the thread associated with this <tt>ThreadInfo</tt>
|
||||
* for which the thread associated with this {@code ThreadInfo}
|
||||
* is blocked waiting.
|
||||
* This method will return <tt>null</tt> if this thread is not blocked
|
||||
* This method will return {@code null} if this thread is not blocked
|
||||
* waiting for any object or if the object is not owned by any thread.
|
||||
*
|
||||
* @return the name of the thread that owns the object
|
||||
* this thread is blocked on;
|
||||
* <tt>null</tt> if this thread is not blocked
|
||||
* {@code null} if this thread is not blocked
|
||||
* or if the object is not owned by any thread.
|
||||
*
|
||||
* @see #getLockInfo
|
||||
@ -520,7 +536,7 @@ public class ThreadInfo {
|
||||
|
||||
/**
|
||||
* Returns the stack trace of the thread
|
||||
* associated with this <tt>ThreadInfo</tt>.
|
||||
* associated with this {@code ThreadInfo}.
|
||||
* If no stack trace was requested for this thread info, this method
|
||||
* will return a zero-length array.
|
||||
* If the returned array is of non-zero length then the first element of
|
||||
@ -532,41 +548,66 @@ public class ThreadInfo {
|
||||
* <p>Some Java virtual machines may, under some circumstances, omit one
|
||||
* or more stack frames from the stack trace. In the extreme case,
|
||||
* a virtual machine that has no stack trace information concerning
|
||||
* the thread associated with this <tt>ThreadInfo</tt>
|
||||
* the thread associated with this {@code ThreadInfo}
|
||||
* is permitted to return a zero-length array from this method.
|
||||
*
|
||||
* @return an array of <tt>StackTraceElement</tt> objects of the thread.
|
||||
* @return an array of {@code StackTraceElement} objects of the thread.
|
||||
*/
|
||||
public StackTraceElement[] getStackTrace() {
|
||||
return stackTrace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the thread associated with this <tt>ThreadInfo</tt>
|
||||
* is suspended. This method returns <tt>true</tt> if
|
||||
* Tests if the thread associated with this {@code ThreadInfo}
|
||||
* is suspended. This method returns {@code true} if
|
||||
* {@link Thread#suspend} has been called.
|
||||
*
|
||||
* @return <tt>true</tt> if the thread is suspended;
|
||||
* <tt>false</tt> otherwise.
|
||||
* @return {@code true} if the thread is suspended;
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
public boolean isSuspended() {
|
||||
return suspended;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the thread associated with this <tt>ThreadInfo</tt>
|
||||
* Tests if the thread associated with this {@code ThreadInfo}
|
||||
* is executing native code via the Java Native Interface (JNI).
|
||||
* The JNI native code does not include
|
||||
* the virtual machine support code or the compiled native
|
||||
* code generated by the virtual machine.
|
||||
*
|
||||
* @return <tt>true</tt> if the thread is executing native code;
|
||||
* <tt>false</tt> otherwise.
|
||||
* @return {@code true} if the thread is executing native code;
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
public boolean isInNative() {
|
||||
return inNative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the thread associated with this {@code ThreadInfo} is
|
||||
* a {@linkplain Thread#isDaemon daemon thread}.
|
||||
*
|
||||
* @return {@code true} if the thread is a daemon thread,
|
||||
* {@code false} otherwise.
|
||||
* @see Thread#isDaemon
|
||||
* @since 1.9
|
||||
*/
|
||||
public boolean isDaemon() {
|
||||
return daemon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@linkplain Thread#getPriority() thread priority} of the
|
||||
* thread associated with this {@code ThreadInfo}.
|
||||
*
|
||||
* @return The priority of the thread associated with this
|
||||
* {@code ThreadInfo}.
|
||||
* @since 1.9
|
||||
*/
|
||||
public int getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this thread info.
|
||||
* The format of this string depends on the implementation.
|
||||
@ -580,6 +621,8 @@ public class ThreadInfo {
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("\"" + getThreadName() + "\"" +
|
||||
(daemon ? " daemon" : "") +
|
||||
" prio=" + priority +
|
||||
" Id=" + getThreadId() + " " +
|
||||
getThreadState());
|
||||
if (getLockName() != null) {
|
||||
@ -647,9 +690,9 @@ public class ThreadInfo {
|
||||
private static final int MAX_FRAMES = 8;
|
||||
|
||||
/**
|
||||
* Returns a <tt>ThreadInfo</tt> object represented by the
|
||||
* given <tt>CompositeData</tt>.
|
||||
* The given <tt>CompositeData</tt> must contain the following attributes
|
||||
* Returns a {@code ThreadInfo} object represented by the
|
||||
* given {@code CompositeData}.
|
||||
* The given {@code CompositeData} must contain the following attributes
|
||||
* unless otherwise specified below:
|
||||
* <blockquote>
|
||||
* <table border summary="The attributes and their types the given CompositeData contains">
|
||||
@ -659,67 +702,67 @@ public class ThreadInfo {
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>threadId</td>
|
||||
* <td><tt>java.lang.Long</tt></td>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>threadName</td>
|
||||
* <td><tt>java.lang.String</tt></td>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>threadState</td>
|
||||
* <td><tt>java.lang.String</tt></td>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>suspended</td>
|
||||
* <td><tt>java.lang.Boolean</tt></td>
|
||||
* <td>{@code java.lang.Boolean}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>inNative</td>
|
||||
* <td><tt>java.lang.Boolean</tt></td>
|
||||
* <td>{@code java.lang.Boolean}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>blockedCount</td>
|
||||
* <td><tt>java.lang.Long</tt></td>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>blockedTime</td>
|
||||
* <td><tt>java.lang.Long</tt></td>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>waitedCount</td>
|
||||
* <td><tt>java.lang.Long</tt></td>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>waitedTime</td>
|
||||
* <td><tt>java.lang.Long</tt></td>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>lockInfo</td>
|
||||
* <td><tt>javax.management.openmbean.CompositeData</tt>
|
||||
* <td>{@code javax.management.openmbean.CompositeData}
|
||||
* - the mapped type for {@link LockInfo} as specified in the
|
||||
* {@link LockInfo#from} method.
|
||||
* <p>
|
||||
* If <tt>cd</tt> does not contain this attribute,
|
||||
* the <tt>LockInfo</tt> object will be constructed from
|
||||
* the value of the <tt>lockName</tt> attribute. </td>
|
||||
* If {@code cd} does not contain this attribute,
|
||||
* the {@code LockInfo} object will be constructed from
|
||||
* the value of the {@code lockName} attribute. </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>lockName</td>
|
||||
* <td><tt>java.lang.String</tt></td>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>lockOwnerId</td>
|
||||
* <td><tt>java.lang.Long</tt></td>
|
||||
* <td>{@code java.lang.Long}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>lockOwnerName</td>
|
||||
* <td><tt>java.lang.String</tt></td>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><a name="StackTrace">stackTrace</a></td>
|
||||
* <td><tt>javax.management.openmbean.CompositeData[]</tt>
|
||||
* <td>{@code javax.management.openmbean.CompositeData[]}
|
||||
* <p>
|
||||
* Each element is a <tt>CompositeData</tt> representing
|
||||
* Each element is a {@code CompositeData} representing
|
||||
* StackTraceElement containing the following attributes:
|
||||
* <blockquote>
|
||||
* <table cellspacing=1 cellpadding=0 summary="The attributes and their types the given CompositeData contains">
|
||||
@ -729,23 +772,23 @@ public class ThreadInfo {
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>className</td>
|
||||
* <td><tt>java.lang.String</tt></td>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>methodName</td>
|
||||
* <td><tt>java.lang.String</tt></td>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>fileName</td>
|
||||
* <td><tt>java.lang.String</tt></td>
|
||||
* <td>{@code java.lang.String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>lineNumber</td>
|
||||
* <td><tt>java.lang.Integer</tt></td>
|
||||
* <td>{@code java.lang.Integer}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>nativeMethod</td>
|
||||
* <td><tt>java.lang.Boolean</tt></td>
|
||||
* <td>{@code java.lang.Boolean}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
* </blockquote>
|
||||
@ -753,35 +796,43 @@ public class ThreadInfo {
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>lockedMonitors</td>
|
||||
* <td><tt>javax.management.openmbean.CompositeData[]</tt>
|
||||
* <td>{@code javax.management.openmbean.CompositeData[]}
|
||||
* whose element type is the mapped type for
|
||||
* {@link MonitorInfo} as specified in the
|
||||
* {@link MonitorInfo#from Monitor.from} method.
|
||||
* <p>
|
||||
* If <tt>cd</tt> does not contain this attribute,
|
||||
* If {@code cd} does not contain this attribute,
|
||||
* this attribute will be set to an empty array. </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>lockedSynchronizers</td>
|
||||
* <td><tt>javax.management.openmbean.CompositeData[]</tt>
|
||||
* <td>{@code javax.management.openmbean.CompositeData[]}
|
||||
* whose element type is the mapped type for
|
||||
* {@link LockInfo} as specified in the {@link LockInfo#from} method.
|
||||
* <p>
|
||||
* If <tt>cd</tt> does not contain this attribute,
|
||||
* If {@code cd} does not contain this attribute,
|
||||
* this attribute will be set to an empty array. </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>daemon</td>
|
||||
* <td>{@code java.lang.Boolean}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>priority</td>
|
||||
* <td>{@code java.lang.Integer}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
* </blockquote>
|
||||
*
|
||||
* @param cd <tt>CompositeData</tt> representing a <tt>ThreadInfo</tt>
|
||||
* @param cd {@code CompositeData} representing a {@code ThreadInfo}
|
||||
*
|
||||
* @throws IllegalArgumentException if <tt>cd</tt> does not
|
||||
* represent a <tt>ThreadInfo</tt> with the attributes described
|
||||
* @throws IllegalArgumentException if {@code cd} does not
|
||||
* represent a {@code ThreadInfo} with the attributes described
|
||||
* above.
|
||||
*
|
||||
* @return a <tt>ThreadInfo</tt> object represented
|
||||
* by <tt>cd</tt> if <tt>cd</tt> is not <tt>null</tt>;
|
||||
* <tt>null</tt> otherwise.
|
||||
* @return a {@code ThreadInfo} object represented
|
||||
* by {@code cd} if {@code cd} is not {@code null};
|
||||
* {@code null} otherwise.
|
||||
*/
|
||||
public static ThreadInfo from(CompositeData cd) {
|
||||
if (cd == null) {
|
||||
@ -798,12 +849,12 @@ public class ThreadInfo {
|
||||
/**
|
||||
* Returns an array of {@link MonitorInfo} objects, each of which
|
||||
* represents an object monitor currently locked by the thread
|
||||
* associated with this <tt>ThreadInfo</tt>.
|
||||
* associated with this {@code ThreadInfo}.
|
||||
* If no locked monitor was requested for this thread info or
|
||||
* no monitor is locked by the thread, this method
|
||||
* will return a zero-length array.
|
||||
*
|
||||
* @return an array of <tt>MonitorInfo</tt> objects representing
|
||||
* @return an array of {@code MonitorInfo} objects representing
|
||||
* the object monitors locked by the thread.
|
||||
*
|
||||
* @since 1.6
|
||||
@ -816,11 +867,11 @@ public class ThreadInfo {
|
||||
* Returns an array of {@link LockInfo} objects, each of which
|
||||
* represents an <a href="LockInfo.html#OwnableSynchronizer">ownable
|
||||
* synchronizer</a> currently locked by the thread associated with
|
||||
* this <tt>ThreadInfo</tt>. If no locked synchronizer was
|
||||
* this {@code ThreadInfo}. If no locked synchronizer was
|
||||
* requested for this thread info or no synchronizer is locked by
|
||||
* the thread, this method will return a zero-length array.
|
||||
*
|
||||
* @return an array of <tt>LockInfo</tt> objects representing
|
||||
* @return an array of {@code LockInfo} objects representing
|
||||
* the ownable synchronizers locked by the thread.
|
||||
*
|
||||
* @since 1.6
|
||||
|
@ -43,23 +43,30 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
private final ThreadInfo threadInfo;
|
||||
private final CompositeData cdata;
|
||||
private final boolean currentVersion;
|
||||
private final boolean hasV6;
|
||||
|
||||
private ThreadInfoCompositeData(ThreadInfo ti) {
|
||||
this.threadInfo = ti;
|
||||
this.currentVersion = true;
|
||||
this.cdata = null;
|
||||
this.hasV6 = true;
|
||||
}
|
||||
|
||||
private ThreadInfoCompositeData(CompositeData cd) {
|
||||
this.threadInfo = null;
|
||||
this.currentVersion = ThreadInfoCompositeData.isCurrentVersion(cd);
|
||||
this.cdata = cd;
|
||||
this.hasV6 = ThreadInfoCompositeData.hasV6(cd);
|
||||
}
|
||||
|
||||
public ThreadInfo getThreadInfo() {
|
||||
return threadInfo;
|
||||
}
|
||||
|
||||
public boolean hasV6() {
|
||||
return hasV6;
|
||||
}
|
||||
|
||||
public boolean isCurrentVersion() {
|
||||
return currentVersion;
|
||||
}
|
||||
@ -124,6 +131,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
threadInfo.isInNative(),
|
||||
lockedMonitorsData,
|
||||
lockedSyncsData,
|
||||
threadInfo.isDaemon(),
|
||||
threadInfo.getPriority(),
|
||||
};
|
||||
|
||||
try {
|
||||
@ -151,6 +160,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
private static final String STACK_TRACE = "stackTrace";
|
||||
private static final String SUSPENDED = "suspended";
|
||||
private static final String IN_NATIVE = "inNative";
|
||||
private static final String DAEMON = "daemon";
|
||||
private static final String PRIORITY = "priority";
|
||||
private static final String LOCKED_MONITORS = "lockedMonitors";
|
||||
private static final String LOCKED_SYNCS = "lockedSynchronizers";
|
||||
|
||||
@ -171,6 +182,8 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
IN_NATIVE,
|
||||
LOCKED_MONITORS,
|
||||
LOCKED_SYNCS,
|
||||
DAEMON,
|
||||
PRIORITY,
|
||||
};
|
||||
|
||||
// New attributes added in 6.0 ThreadInfo
|
||||
@ -180,9 +193,16 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
LOCKED_SYNCS,
|
||||
};
|
||||
|
||||
private static final String[] threadInfoV9Attributes = {
|
||||
DAEMON,
|
||||
PRIORITY,
|
||||
};
|
||||
|
||||
// Current version of ThreadInfo
|
||||
private static final CompositeType threadInfoCompositeType;
|
||||
// Previous version of ThreadInfo
|
||||
private static final CompositeType threadInfoV6CompositeType;
|
||||
// Previous-previous version of ThreadInfo
|
||||
private static final CompositeType threadInfoV5CompositeType;
|
||||
private static final CompositeType lockInfoCompositeType;
|
||||
static {
|
||||
@ -193,7 +213,7 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
String[] itemNames =
|
||||
threadInfoCompositeType.keySet().toArray(new String[0]);
|
||||
int numV5Attributes = threadInfoItemNames.length -
|
||||
threadInfoV6Attributes.length;
|
||||
threadInfoV6Attributes.length - threadInfoV9Attributes.length;
|
||||
String[] v5ItemNames = new String[numV5Attributes];
|
||||
String[] v5ItemDescs = new String[numV5Attributes];
|
||||
OpenType<?>[] v5ItemTypes = new OpenType<?>[numV5Attributes];
|
||||
@ -213,6 +233,31 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
v5ItemNames,
|
||||
v5ItemDescs,
|
||||
v5ItemTypes);
|
||||
|
||||
|
||||
// Form a CompositeType for JDK 6.0 ThreadInfo version
|
||||
int numV6Attributes = threadInfoItemNames.length -
|
||||
threadInfoV9Attributes.length;
|
||||
String[] v6ItemNames = new String[numV6Attributes];
|
||||
String[] v6ItemDescs = new String[numV6Attributes];
|
||||
OpenType<?>[] v6ItemTypes = new OpenType<?>[numV6Attributes];
|
||||
i = 0;
|
||||
for (String n : itemNames) {
|
||||
if (isV5Attribute(n) || isV6Attribute(n)) {
|
||||
v6ItemNames[i] = n;
|
||||
v6ItemDescs[i] = threadInfoCompositeType.getDescription(n);
|
||||
v6ItemTypes[i] = threadInfoCompositeType.getType(n);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
threadInfoV6CompositeType =
|
||||
new CompositeType("java.lang.management.ThreadInfo",
|
||||
"Java SE 6 java.lang.management.ThreadInfo",
|
||||
v6ItemNames,
|
||||
v6ItemDescs,
|
||||
v6ItemTypes);
|
||||
|
||||
} catch (OpenDataException e) {
|
||||
// Should never reach here
|
||||
throw new AssertionError(e);
|
||||
@ -236,6 +281,20 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (String n : threadInfoV9Attributes) {
|
||||
if (itemName.equals(n)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isV6Attribute(String itemName) {
|
||||
for (String n : threadInfoV9Attributes) {
|
||||
if (itemName.equals(n)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -247,6 +306,15 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
return isTypeMatched(threadInfoCompositeType, cd.getCompositeType());
|
||||
}
|
||||
|
||||
private static boolean hasV6(CompositeData cd) {
|
||||
if (cd == null) {
|
||||
throw new NullPointerException("Null CompositeData");
|
||||
}
|
||||
|
||||
return isTypeMatched(threadInfoCompositeType, cd.getCompositeType()) ||
|
||||
isTypeMatched(threadInfoV6CompositeType, cd.getCompositeType());
|
||||
}
|
||||
|
||||
public long threadId() {
|
||||
return getLong(cdata, THREAD_ID);
|
||||
}
|
||||
@ -304,6 +372,14 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
return getBoolean(cdata, IN_NATIVE);
|
||||
}
|
||||
|
||||
public boolean isDaemon() {
|
||||
return getBoolean(cdata, DAEMON);
|
||||
}
|
||||
|
||||
public int getPriority(){
|
||||
return getInt(cdata, PRIORITY);
|
||||
}
|
||||
|
||||
public StackTraceElement[] stackTrace() {
|
||||
CompositeData[] stackTraceData =
|
||||
(CompositeData[]) cdata.get(STACK_TRACE);
|
||||
@ -368,9 +444,10 @@ public class ThreadInfoCompositeData extends LazyCompositeData {
|
||||
if (!isTypeMatched(threadInfoCompositeType, type)) {
|
||||
currentVersion = false;
|
||||
// check if cd is an older version
|
||||
if (!isTypeMatched(threadInfoV5CompositeType, type)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected composite type for ThreadInfo");
|
||||
if (!isTypeMatched(threadInfoV5CompositeType, type) &&
|
||||
!isTypeMatched(threadInfoV6CompositeType, type)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected composite type for ThreadInfo");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,6 +147,11 @@ public class ThreadInfoCompositeData {
|
||||
info.getLockOwnerName() + " expected = " +
|
||||
values[LOCK_OWNER_NAME]);
|
||||
}
|
||||
if (!values[DAEMON].equals(info.isDaemon())) {
|
||||
throw new RuntimeException("Daemon = " +
|
||||
info.isDaemon() + " expected = " +
|
||||
values[DAEMON]);
|
||||
}
|
||||
|
||||
checkStackTrace(info.getStackTrace());
|
||||
|
||||
@ -258,8 +263,11 @@ public class ThreadInfoCompositeData {
|
||||
private static final int SUSPENDED = 11;
|
||||
private static final int IN_NATIVE = 12;
|
||||
private static final int NUM_V5_ATTS = 13;
|
||||
// JDK 6.0 ThreadInfo attribtues
|
||||
// JDK 6.0 ThreadInfo attributes
|
||||
private static final int LOCK_INFO = 13;
|
||||
// JDK 9.0 ThreadInfo attributes
|
||||
private static final int DAEMON = 14;
|
||||
private static final int PRIORITY = 15;
|
||||
|
||||
private static final String[] validItemNames = {
|
||||
"threadId",
|
||||
@ -276,6 +284,8 @@ public class ThreadInfoCompositeData {
|
||||
"suspended",
|
||||
"inNative",
|
||||
"lockInfo",
|
||||
"daemon",
|
||||
"priority",
|
||||
};
|
||||
|
||||
private static OpenType[] validItemTypes = {
|
||||
@ -293,6 +303,8 @@ public class ThreadInfoCompositeData {
|
||||
SimpleType.BOOLEAN,
|
||||
SimpleType.BOOLEAN,
|
||||
null, // CompositeType for LockInfo
|
||||
SimpleType.BOOLEAN,
|
||||
SimpleType.INTEGER,
|
||||
};
|
||||
|
||||
private static Object[] values = {
|
||||
@ -310,6 +322,8 @@ public class ThreadInfoCompositeData {
|
||||
new Boolean(false),
|
||||
new Boolean(false),
|
||||
null, // To be initialized to lockInfoCD
|
||||
new Boolean(false),
|
||||
Thread.NORM_PRIORITY,
|
||||
};
|
||||
|
||||
private static final String[] steItemNames = {
|
||||
@ -381,6 +395,8 @@ public class ThreadInfoCompositeData {
|
||||
"suspended",
|
||||
"inNative",
|
||||
"lockInfo",
|
||||
"daemon",
|
||||
"priority",
|
||||
};
|
||||
private static final OpenType[] badItemTypes = {
|
||||
SimpleType.LONG,
|
||||
@ -397,6 +413,8 @@ public class ThreadInfoCompositeData {
|
||||
SimpleType.BOOLEAN,
|
||||
SimpleType.BOOLEAN,
|
||||
SimpleType.LONG, // bad type
|
||||
SimpleType.BOOLEAN,
|
||||
SimpleType.INTEGER,
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.management.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6588467
|
||||
* @summary Basic test of ThreadInfo.isDaemon
|
||||
* @author Jeremy Manson
|
||||
*/
|
||||
public class ThreadDaemonTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final int NUM_THREADS = 20;
|
||||
final String THREAD_PREFIX = "ThreadDaemonTest-";
|
||||
|
||||
final CountDownLatch started = new CountDownLatch(NUM_THREADS);
|
||||
final CountDownLatch finished = new CountDownLatch(1);
|
||||
final AtomicReference<Exception> fail = new AtomicReference<>(null);
|
||||
|
||||
Thread[] allThreads = new Thread[NUM_THREADS];
|
||||
ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
|
||||
Random rand = new Random();
|
||||
|
||||
for (int i = 0; i < NUM_THREADS; i++) {
|
||||
allThreads[i] = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
started.countDown();
|
||||
finished.await();
|
||||
} catch (InterruptedException e) {
|
||||
fail.set(new Exception(
|
||||
"Unexpected InterruptedException"));
|
||||
}
|
||||
}
|
||||
}, THREAD_PREFIX + i);
|
||||
allThreads[i].setDaemon(rand.nextBoolean());
|
||||
allThreads[i].start();
|
||||
}
|
||||
|
||||
started.await();
|
||||
try {
|
||||
ThreadInfo[] allThreadInfos = mbean.dumpAllThreads(false, false);
|
||||
int count = 0;
|
||||
for (int i = 0; i < allThreadInfos.length; i++) {
|
||||
String threadName = allThreadInfos[i].getThreadName();
|
||||
if (threadName.startsWith(THREAD_PREFIX)) {
|
||||
count++;
|
||||
String[] nameAndNumber = threadName.split("-");
|
||||
int threadNum = Integer.parseInt(nameAndNumber[1]);
|
||||
if (allThreads[threadNum].isDaemon() !=
|
||||
allThreadInfos[i].isDaemon()) {
|
||||
throw new RuntimeException(
|
||||
allThreads[threadNum] + " is not like " +
|
||||
allThreadInfos[i] + ". TEST FAILED.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count != NUM_THREADS) {
|
||||
throw new RuntimeException("Wrong number of threads examined");
|
||||
}
|
||||
}
|
||||
finally { finished.countDown(); }
|
||||
|
||||
for (int i = 0; i < NUM_THREADS; i++) {
|
||||
allThreads[i].join();
|
||||
}
|
||||
if (fail.get() != null) {
|
||||
throw fail.get();
|
||||
}
|
||||
}
|
||||
}
|
@ -34,6 +34,7 @@ public class ThreadDump {
|
||||
|
||||
public static void printThreadInfo(ThreadInfo ti) {
|
||||
StringBuilder sb = new StringBuilder("\"" + ti.getThreadName() + "\"" +
|
||||
(ti.isDaemon() ? " daemon" : "") +
|
||||
" Id=" + ti.getThreadId() +
|
||||
" in " + ti.getThreadState());
|
||||
if (ti.getLockName() != null) {
|
||||
|
Loading…
Reference in New Issue
Block a user