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