# HG changeset patch # User jmanson # Date 1424767589 -3600 # Node ID 55f7a91aaa32c172868548313e4e4c4d1dedcf18 # Parent 56267f38f743f3aaf05d7f88c416ba289fd12198 6588467: Add isDaemon() and getPriority() to ThreadInfo Reviewed-by: mchung, sla, dholmes, martin diff -r 56267f38f743 -r 55f7a91aaa32 jdk/src/java.management/share/classes/java/lang/management/ThreadInfo.java --- a/jdk/src/java.management/share/classes/java/lang/management/ThreadInfo.java Mon Feb 23 11:40:48 2015 -0800 +++ b/jdk/src/java.management/share/classes/java/lang/management/ThreadInfo.java Tue Feb 24 09:46:29 2015 +0100 @@ -31,12 +31,13 @@ import static java.lang.Thread.State.*; /** - * Thread information. ThreadInfo contains the information + * Thread information. {@code ThreadInfo} contains the information * about a thread including: *

General thread information

* * *

Execution information

@@ -57,6 +58,7 @@ *
  • List of object monitors locked by the thread.
  • *
  • List of * ownable synchronizers locked by the thread.
  • + *
  • Thread priority
  • * * *

    Synchronization Statistics

    @@ -78,7 +80,7 @@ * the system, not for synchronization control. * *

    MXBean Mapping

    - * ThreadInfo 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 @@ 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 @@ 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 @@ } /* - * Constructs a ThreadInfo object from a + * Constructs a {@code ThreadInfo} object from a * {@link CompositeData CompositeData}. */ private ThreadInfo(CompositeData cd) { @@ -277,7 +283,7 @@ 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 @@ 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 ThreadInfo. + * Returns the ID of the thread associated with this {@code ThreadInfo}. * * @return the ID of the associated thread. */ @@ -312,7 +328,7 @@ } /** - * Returns the name of the thread associated with this ThreadInfo. + * Returns the name of the thread associated with this {@code ThreadInfo}. * * @return the name of the associated thread. */ @@ -321,9 +337,9 @@ } /** - * Returns the state of the thread associated with this ThreadInfo. + * Returns the state of the thread associated with this {@code ThreadInfo}. * - * @return Thread.State of the associated thread. + * @return {@code Thread.State} of the associated thread. */ public Thread.State getThreadState() { return threadState; @@ -331,13 +347,13 @@ /** * Returns the approximate accumulated elapsed time (in milliseconds) - * that the thread associated with this ThreadInfo + * 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 -1 if thread contention monitoring + * This method returns {@code -1} if thread contention monitoring * is disabled. * *

    The Java virtual machine may measure the time with a high @@ -345,8 +361,8 @@ * the thread contention monitoring is reenabled. * * @return the approximate accumulated elapsed time in milliseconds - * that a thread entered the BLOCKED state; - * -1 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 @@ /** * Returns the total number of times that - * the thread associated with this ThreadInfo + * 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 BLOCKED state. + * entered the {@code BLOCKED} state. */ public long getBlockedCount() { return blockedCount; @@ -374,14 +390,14 @@ /** * Returns the approximate accumulated elapsed time (in milliseconds) - * that the thread associated with this ThreadInfo + * 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 -1 if thread contention monitoring + * This method returns {@code -1} if thread contention monitoring * is disabled. * *

    The Java virtual machine may measure the time with a high @@ -389,9 +405,9 @@ * the thread contention monitoring is reenabled. * * @return the approximate accumulated elapsed time in milliseconds - * that a thread has been in the WAITING or - * TIMED_WAITING state; - * -1 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 @@ /** * Returns the total number of times that - * the thread associated with this ThreadInfo + * 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 WAITING or TIMED_WAITING state. + * was in the {@code WAITING} or {@code TIMED_WAITING} state. */ public long getWaitedCount() { return waitedCount; } /** - * Returns the LockInfo of an object for which - * the thread associated with this ThreadInfo + * 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: *

    * - *

    This method returns null if the thread is not in any of + *

    This method returns {@code null} if the thread is not in any of * the above conditions. * - * @return LockInfo of an object for which the thread - * is blocked waiting if any; null 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 @@ /** * Returns the {@link LockInfo#toString string representation} * of an object for which the thread associated with this - * ThreadInfo is blocked waiting. + * {@code ThreadInfo} is blocked waiting. * This method is equivalent to calling: *

    *
          * getLockInfo().toString()
          * 
    * - *

    This method will return null 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 string representation of the object on which * the thread is blocked if any; - * null otherwise. + * {@code null} otherwise. * * @see #getLockInfo */ @@ -484,14 +500,14 @@ /** * Returns the ID of the thread which owns the object - * for which the thread associated with this ThreadInfo + * for which the thread associated with this {@code ThreadInfo} * is blocked waiting. - * This method will return -1 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; - * -1 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 @@ /** * Returns the name of the thread which owns the object - * for which the thread associated with this ThreadInfo + * for which the thread associated with this {@code ThreadInfo} * is blocked waiting. - * This method will return null 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; - * null 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 @@ /** * Returns the stack trace of the thread - * associated with this ThreadInfo. + * 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,42 +548,67 @@ *

    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 ThreadInfo + * the thread associated with this {@code ThreadInfo} * is permitted to return a zero-length array from this method. * - * @return an array of StackTraceElement 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 ThreadInfo - * is suspended. This method returns true 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 true if the thread is suspended; - * false otherwise. + * @return {@code true} if the thread is suspended; + * {@code false} otherwise. */ public boolean isSuspended() { return suspended; } /** - * Tests if the thread associated with this ThreadInfo + * 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 true if the thread is executing native code; - * false 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. * The returned string will typically include @@ -580,6 +621,8 @@ */ public String toString() { StringBuilder sb = new StringBuilder("\"" + getThreadName() + "\"" + + (daemon ? " daemon" : "") + + " prio=" + priority + " Id=" + getThreadId() + " " + getThreadState()); if (getLockName() != null) { @@ -647,9 +690,9 @@ private static final int MAX_FRAMES = 8; /** - * Returns a ThreadInfo object represented by the - * given CompositeData. - * The given CompositeData 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: *

    * @@ -659,67 +702,67 @@ * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * If {@code cd} does not contain this attribute, + * the {@code LockInfo} object will be constructed from + * the value of the {@code lockName} attribute. * * * - * + * * * * - * + * * * * - * + * * * * - * * * - * * * * - * * + * + * + * + * + * + * + * + * *
    threadIdjava.lang.Long{@code java.lang.Long}
    threadNamejava.lang.String{@code java.lang.String}
    threadStatejava.lang.String{@code java.lang.String}
    suspendedjava.lang.Boolean{@code java.lang.Boolean}
    inNativejava.lang.Boolean{@code java.lang.Boolean}
    blockedCountjava.lang.Long{@code java.lang.Long}
    blockedTimejava.lang.Long{@code java.lang.Long}
    waitedCountjava.lang.Long{@code java.lang.Long}
    waitedTimejava.lang.Long{@code java.lang.Long}
    lockInfojavax.management.openmbean.CompositeData + * {@code javax.management.openmbean.CompositeData} * - the mapped type for {@link LockInfo} as specified in the * {@link LockInfo#from} method. *

    - * If cd does not contain this attribute, - * the LockInfo object will be constructed from - * the value of the lockName attribute.

    lockNamejava.lang.String{@code java.lang.String}
    lockOwnerIdjava.lang.Long{@code java.lang.Long}
    lockOwnerNamejava.lang.String{@code java.lang.String}
    stackTracejavax.management.openmbean.CompositeData[] + * {@code javax.management.openmbean.CompositeData[]} *

    - * Each element is a CompositeData representing + * Each element is a {@code CompositeData} representing * StackTraceElement containing the following attributes: *

    * @@ -729,23 +772,23 @@ * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * *
    classNamejava.lang.String{@code java.lang.String}
    methodNamejava.lang.String{@code java.lang.String}
    fileNamejava.lang.String{@code java.lang.String}
    lineNumberjava.lang.Integer{@code java.lang.Integer}
    nativeMethodjava.lang.Boolean{@code java.lang.Boolean}
    *
    @@ -753,35 +796,43 @@ *
    lockedMonitorsjavax.management.openmbean.CompositeData[] + * {@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. *

    - * If cd does not contain this attribute, + * If {@code cd} does not contain this attribute, * this attribute will be set to an empty array.

    lockedSynchronizersjavax.management.openmbean.CompositeData[] + * {@code javax.management.openmbean.CompositeData[]} * whose element type is the mapped type for * {@link LockInfo} as specified in the {@link LockInfo#from} method. *

    - * If cd does not contain this attribute, + * If {@code cd} does not contain this attribute, * this attribute will be set to an empty array.

    daemon{@code java.lang.Boolean}
    priority{@code java.lang.Integer}
    *
    * - * @param cd CompositeData representing a ThreadInfo + * @param cd {@code CompositeData} representing a {@code ThreadInfo} * - * @throws IllegalArgumentException if cd does not - * represent a ThreadInfo with the attributes described + * @throws IllegalArgumentException if {@code cd} does not + * represent a {@code ThreadInfo} with the attributes described * above. * - * @return a ThreadInfo object represented - * by cd if cd is not null; - * null 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 @@ /** * Returns an array of {@link MonitorInfo} objects, each of which * represents an object monitor currently locked by the thread - * associated with this ThreadInfo. + * 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 MonitorInfo objects representing + * @return an array of {@code MonitorInfo} objects representing * the object monitors locked by the thread. * * @since 1.6 @@ -816,11 +867,11 @@ * Returns an array of {@link LockInfo} objects, each of which * represents an ownable * synchronizer currently locked by the thread associated with - * this ThreadInfo. 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 LockInfo objects representing + * @return an array of {@code LockInfo} objects representing * the ownable synchronizers locked by the thread. * * @since 1.6 diff -r 56267f38f743 -r 55f7a91aaa32 jdk/src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java --- a/jdk/src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java Mon Feb 23 11:40:48 2015 -0800 +++ b/jdk/src/java.management/share/classes/sun/management/ThreadInfoCompositeData.java Tue Feb 24 09:46:29 2015 +0100 @@ -43,23 +43,30 @@ 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 @@ threadInfo.isInNative(), lockedMonitorsData, lockedSyncsData, + threadInfo.isDaemon(), + threadInfo.getPriority(), }; try { @@ -151,6 +160,8 @@ 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 @@ IN_NATIVE, LOCKED_MONITORS, LOCKED_SYNCS, + DAEMON, + PRIORITY, }; // New attributes added in 6.0 ThreadInfo @@ -180,9 +193,16 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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"); } } diff -r 56267f38f743 -r 55f7a91aaa32 jdk/test/java/lang/management/CompositeData/ThreadInfoCompositeData.java --- a/jdk/test/java/lang/management/CompositeData/ThreadInfoCompositeData.java Mon Feb 23 11:40:48 2015 -0800 +++ b/jdk/test/java/lang/management/CompositeData/ThreadInfoCompositeData.java Tue Feb 24 09:46:29 2015 +0100 @@ -147,6 +147,11 @@ 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 @@ 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 @@ "suspended", "inNative", "lockInfo", + "daemon", + "priority", }; private static OpenType[] validItemTypes = { @@ -293,6 +303,8 @@ SimpleType.BOOLEAN, SimpleType.BOOLEAN, null, // CompositeType for LockInfo + SimpleType.BOOLEAN, + SimpleType.INTEGER, }; private static Object[] values = { @@ -310,6 +322,8 @@ 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 @@ "suspended", "inNative", "lockInfo", + "daemon", + "priority", }; private static final OpenType[] badItemTypes = { SimpleType.LONG, @@ -397,6 +413,8 @@ SimpleType.BOOLEAN, SimpleType.BOOLEAN, SimpleType.LONG, // bad type + SimpleType.BOOLEAN, + SimpleType.INTEGER, }; } diff -r 56267f38f743 -r 55f7a91aaa32 jdk/test/java/lang/management/ThreadMXBean/ThreadDaemonTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadDaemonTest.java Tue Feb 24 09:46:29 2015 +0100 @@ -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 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(); + } + } +} diff -r 56267f38f743 -r 55f7a91aaa32 jdk/test/java/lang/management/ThreadMXBean/ThreadDump.java --- a/jdk/test/java/lang/management/ThreadMXBean/ThreadDump.java Mon Feb 23 11:40:48 2015 -0800 +++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadDump.java Tue Feb 24 09:46:29 2015 +0100 @@ -34,6 +34,7 @@ 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) {