/* 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 java.util.Arrays;

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>
 * <li>The current locks held on object monitors by the thread.</li>
 * <li>The current locks held on ownable synchronizers by the thread.</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 Thread.State 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;

  /**
   * The array of information on monitors locked by the thread.
   */
  private MonitorInfo[] lockedMonitors;

  /**
   * The array of information on ownable synchronizers locked
   * by the thread.
   */
  private LockInfo[] lockedSynchronizers;

  /**
   * Cache a local reference to the thread management bean.
   */
  private static ThreadMXBean bean = null;

  /**
   * Cache the {@link javax.management.openmbean.CompositeType}
   * for the {@link StackTraceElement}.
   */
  private static CompositeType seType;

  /**
   * 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)
   * @param lockedMonitors an array of {@link MonitorInfo} objects
   *                       representing locks held on object monitors
   *                       by the thread.
   * @param lockedSynchronizers an array of {@link LockInfo} objects
   *                            representing locks held on ownable
   *                            synchronizers by the thread.
   *
   * @since 1.6
   */
  private ThreadInfo(long threadId, String threadName, Thread.State threadState,
                     long blockedCount, long blockedTime, String lockName,
                     long lockOwnerId, String lockOwnerName, long waitedCount,
                     long waitedTime, boolean isInNative, boolean isSuspended,
                     StackTraceElement[] trace, MonitorInfo[] lockedMonitors,
                     LockInfo[] lockedSynchronizers)
  {
    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;
    this.lockedMonitors = lockedMonitors;
    this.lockedSynchronizers = lockedSynchronizers;
  }

  /**
   * 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());
  }

  /**
   * Returns the {@link javax.management.openmbean.CompositeType} for
   * a {@link StackTraceElement}.
   *
   * @return the type for the stack trace element.
   */
  static CompositeType getStackTraceType()
  {
    if (seType == null)
      try
        {
          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
                                     });
        }
      catch (OpenDataException e)
        {
          throw new IllegalStateException("Something went wrong in creating " +
                                          "the composite data type for the " +
                                          "stack trace element.", e);
        }
    return seType;
  }

  /**
   * <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
      {
        checkAttribute(type, "StackTrace",
                       new ArrayType(1, getStackTraceType()));
      }
    catch (OpenDataException e)
      {
        throw new IllegalStateException("Something went wrong in creating " +
                                        "the array for the stack trace element.",
                                        e);
      }
    OpenType foundType = type.getType("LockedMonitors");
    if (foundType != null)
      try
        {
          CompositeType mType = new CompositeType(MonitorInfo.class.getName(),
                                                  "Information on a object monitor lock",
                                                  new String[] { "ClassName",
                                                                 "IdentityHashCode",
                                                                 "LockedStackDepth",
                                                                 "LockedStackFrame"
                                                  },
                                                  new String[] { "Name of the class",
                                                                 "Identity hash code " +
                                                                 "of the class",
                                                                 "Stack depth at time " +
                                                                 "of lock",
                                                                 "Stack frame at time " +
                                                                 "of lock",
                                                  },
                                                  new OpenType[] {
                                                    SimpleType.STRING, SimpleType.INTEGER,
                                                    SimpleType.INTEGER, getStackTraceType()
                                                  });
          if (!(foundType.equals(new ArrayType(1, mType))))
            throw new IllegalArgumentException("Field LockedMonitors is not of " +
                                               "type " + mType.getClassName());
        }
    catch (OpenDataException e)
      {
        throw new IllegalStateException("Something went wrong in creating " +
                                        "the composite data type for the " +
                                        "object monitor information array.", e);
      }
    foundType = type.getType("LockedSynchronizers");
    if (foundType != null)
      try
        {
          CompositeType lType = new CompositeType(LockInfo.class.getName(),
                                                  "Information on a lock",
                                                  new String[] { "ClassName",
                                                                 "IdentityHashCode"
                                                  },
                                                  new String[] { "Name of the class",
                                                                 "Identity hash code " +
                                                                 "of the class"
                                                  },
                                                  new OpenType[] {
                                                    SimpleType.STRING, SimpleType.INTEGER
                                                  });
          if (!(foundType.equals(new ArrayType(1, lType))))
            throw new IllegalArgumentException("Field LockedSynchronizers is not of " +
                                               "type " + lType.getClassName());
        }
    catch (OpenDataException e)
      {
        throw new IllegalStateException("Something went wrong in creating " +
                                        "the composite data type for the " +
                                        "ownable synchronizerinformation array.", 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());
    MonitorInfo[] mInfo;
    if (data.containsKey("LockedMonitors"))
      {
        CompositeData[] dmInfos = (CompositeData[]) data.get("LockedMonitors");
        mInfo = new MonitorInfo[dmInfos.length];
        for (int a = 0; a < dmInfos.length; ++a)
          mInfo[a] = MonitorInfo.from(dmInfos[a]);
      }
    else
      mInfo = new MonitorInfo[]{};
    LockInfo[] lInfo;
    if (data.containsKey("LockedSynchronizers"))
      {
        CompositeData[] dlInfos = (CompositeData[]) data.get("LockedSynchronizers");
        lInfo = new LockInfo[dlInfos.length];
        for (int a = 0; a < dlInfos.length; ++a)
          lInfo[a] = new LockInfo((String) dlInfos[a].get("ClassName"),
                                  (Integer) dlInfos[a].get("IdentityHashCode"));
      }
    else
      lInfo = new LockInfo[]{};
    return new ThreadInfo(((Long) data.get("ThreadId")).longValue(),
                          (String) data.get("ThreadName"),
                          Thread.State.valueOf((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, mInfo, lInfo);
  }

  /**
   * 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;
  }

  /**
   * Returns an array of {@link MonitorInfo} objects representing
   * information on the locks on object monitors held by the thread.
   * If no locks are held, or such information was not requested
   * on creating this {@link ThreadInfo} object, a zero-length
   * array will be returned.
   *
   * @return information on object monitors locked by this thread.
   */
  public MonitorInfo[] getLockedMonitors()
  {
    return lockedMonitors;
  }

  /**
   * Returns an array of {@link LockInfo} objects representing
   * information on the locks on ownable synchronizers held by the thread.
   * If no locks are held, or such information was not requested
   * on creating this {@link ThreadInfo} object, a zero-length
   * array will be returned.
   *
   * @return information on ownable synchronizers locked by this thread.
   */
  public LockInfo[] getLockedSynchronizers()
  {
    return lockedSynchronizers;
  }

  /**
   * <p>
   * Returns a {@link LockInfo} object representing the
   * lock on which this thread is blocked.  If the thread
   * is not blocked, this method returns <code>null</code>.
   * </p>
   * <p>
   * The thread may be blocked due to one of three reasons:
   * </p>
   * <ol>
   * <li>The thread is in the <code>BLOCKED</code> state
   * waiting to acquire an object monitor in order to enter
   * a synchronized method or block.</li>
   * <li>The thread is in the <code>WAITING</code> or
   * <code>TIMED_WAITING</code> state due to a call to
   * {@link java.lang.Object#wait()}.</li>
   * <li>The thread is in the <code>WAITING</code> or
   * <code>TIMED_WAITING</code> state due to a call
   * to {@link java.util.concurrent.locks.LockSupport#park()}.
   * The lock is the return value of
   * {@link java.util.concurrent.locks.LockSupport#getBlocker()}.</li>
   * </ol>
   *
   * @return a {@link LockInfo} object representing the lock on
   *         which the thread is blocked, or <code>null</code> if
   *         the thread isn't blocked.
   * @since 1.6
   * @see #getLockName()
   */
  public LockInfo getLockInfo()
  {
    String lockName = getLockName();
    int at = lockName.indexOf('@');
    return new LockInfo(lockName.substring(0, at),
                        Integer.decode(lockName.substring(at + 1)));
  }

  /**
   * <p>
   * Returns a {@link java.lang.String} representation of
   * the 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.  The value is the same as would
   * be returned by <code>getLockInfo().toString()</code>
   * </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 (!isThreadBlocked())
      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 (!isThreadBlocked())
      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 (!isThreadBlocked())
      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 Thread.State 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 +
      (isThreadBlocked() ?
       ", lockOwnerId=" + lockOwnerId +
       ", lockOwnerName=" + lockOwnerName : "") +
      ", lockedMonitors=" + Arrays.toString(lockedMonitors) +
      ", lockedSynchronizers=" + Arrays.toString(lockedSynchronizers) +
      "]";
  }

  /**
   * <p>
   * Returns true if the thread is in a blocked state.
   * The thread is regarded as blocked if:
   * </p>
   * <ol>
   * <li>The thread is in the <code>BLOCKED</code> state
   * waiting to acquire an object monitor in order to enter
   * a synchronized method or block.</li>
   * <li>The thread is in the <code>WAITING</code> or
   * <code>TIMED_WAITING</code> state due to a call to
   * {@link java.lang.Object#wait()}.</li>
   * <li>The thread is in the <code>WAITING</code> or
   * <code>TIMED_WAITING</code> state due to a call
   * to {@link java.util.concurrent.locks.LockSupport#park()}.
   * The lock is the return value of
   * {@link java.util.concurrent.locks.LockSupport#getBlocker()}.</li>
   * </ol>
   *
   * @return true if the thread is blocked.
   */
  private boolean isThreadBlocked()
  {
    return (threadState == Thread.State.BLOCKED ||
            threadState == Thread.State.WAITING ||
            threadState == Thread.State.TIMED_WAITING);
  }

}
