/**
* Get a list of all daemon threads. An empty array is
* returned if there are no daemon threads.
*
* @return an array of daemon threads
*/
public static Thread[] getAllDaemonThreads( )
{
final Thread[] allThreads = getAllThreads( );
final Thread[] daemons = new Thread[allThreads.length];
int nDaemon = 0;
for ( Thread thread : allThreads )
if ( thread.isDaemon( ) )
daemons[nDaemon++] = thread;
return java.util.Arrays.copyOf( daemons, nDaemon );
}
/**
* Get a list of all threads with a given thread state.
* Thread states are defined in the Thread.State enum for
* the Thread class. Principal thread states include
* RUNNABLE, WAITING, TIMED_WAITING, and BLOCKED. An
* empty array is returned if there are no threads in
* the chosen state.
*
* @param state the state to look for
* @return an array of threads in that state
*/
public static Thread[] getAllThreads( final Thread.State state )
{
final Thread[] allThreads = getAllThreads( );
final Thread[] found = new Thread[allThreads.length];
int nFound = 0;
for ( Thread thread : allThreads )
if ( thread.getState( ) == state )
found[nFound++] = thread;
return java.util.Arrays.copyOf( found, nFound );
}
/**
* Get the thread with the given name. A null is returned
* if no such thread is found. If more than one thread has
* the same name, the first one found is returned.
*
* @param name the thread name to search for
* @return the thread, or null if not found
* @throws NullPointerException
* if the name is null
*/
public static Thread getThread( final String name )
{
if ( name == null )
throw new NullPointerException( "Null name" );
final Thread[] threads = getAllThreads( );
for ( Thread thread : threads )
if ( thread.getName( ).equals( name ) )
return thread;
return null;
}
/**
* Get the thread with the given ID. A null is returned
* if no such thread is found.
*
* @param id the thread ID to search for
* @return the thread, or null if not found
*/
public static Thread getThread( final long id )
{
final Thread[] threads = getAllThreads( );
for ( Thread thread : threads )
if ( thread.getId( ) == id )
return thread;
return null;
}
/**
* Get the thread for the given thread info. A null
* is returned if the thread cannot be found.
*
* @param info the thread info to search for
* @return the thread, or null if not found
* @throws NullPointerException
* if info is null
*/
public static Thread getThread( final ThreadInfo info )
{
if ( info == null )
throw new NullPointerException( "Null info" );
return getThread( info.getThreadId( ) );
}
// ThreadInfo
/**
* Get a list of all thread info objects. Since there is
* always at least one thread running, there is always at
* least one thread info object. This method never returns
* a null or empty array.
*
* @return an array of thread infos
*/
public static ThreadInfo[] getAllThreadInfos( )
{
final ThreadMXBean thbean =
ManagementFactory.getThreadMXBean( );
final long[] ids = thbean.getAllThreadIds( );
// Get thread info with lock info, when available.
ThreadInfo[] infos;
if ( !thbean.isObjectMonitorUsageSupported( ) ||
!thbean.isSynchronizerUsageSupported( ) )
infos = thbean.getThreadInfo( ids );
else
infos = thbean.getThreadInfo( ids, true, true );
// Clean nulls from array if threads have died.
final ThreadInfo[] notNulls = new ThreadInfo[infos.length];
int nNotNulls = 0;
for ( ThreadInfo info : infos )
if ( info != null )
notNulls[nNotNulls++] = info;
if ( nNotNulls == infos.length )
return infos; // Original had no nulls
return java.util.Arrays.copyOf( notNulls, nNotNulls );
}
/**
* Get the thread info for the thread with the given name.
* A null is returned if no such thread info is found.
* If more than one thread has the same name, the thread
* info for the first one found is returned.
*
* @param name the thread name to search for
* @return the thread info, or null if not found
* @throws NullPointerException
* if the name is null
*/
public static ThreadInfo getThreadInfo( final String name )
{
if ( name == null )
throw new NullPointerException( "Null name" );
final Thread[] threads = getAllThreads( );
for ( Thread thread : threads )
if ( thread.getName( ).equals( name ) )
return getThreadInfo( thread.getId( ) );
return null;
}
/**
* Get the thread info for the thread with the given ID.
* A null is returned if no such thread info is found.
*
* @param id the thread ID to search for
* @return the thread info, or null if not found
* @throws IllegalArgumentException
* if id <= 0
*/
public static ThreadInfo getThreadInfo( final long id )
{
final ThreadMXBean thbean =
ManagementFactory.getThreadMXBean( );
// Get thread info with lock info, when available.
if ( !thbean.isObjectMonitorUsageSupported( ) ||
!thbean.isSynchronizerUsageSupported( ) )
return thbean.getThreadInfo( id );
final ThreadInfo[] infos = thbean.getThreadInfo(
new long[] { id }, true, true );
if ( infos.length == 0 )
return null;
return infos[0];
}
/**
* Get the thread info for the given thread. A null is
* returned if the thread info cannot be found.
*
* @param thread the thread to search for
* @return the thread info, or null if not found
* @throws NullPointerException
* if thread is null
*/
public static ThreadInfo getThreadInfo( final Thread thread )
{
if ( thread == null )
throw new NullPointerException( "Null thread" );
return getThreadInfo( thread.getId( ) );
}
// MonitorInfo and LockInfo
/**
* Get the thread holding a lock on the given object.
* A null is returned if there is no such thread.
*
* @param object the object to look for a lock on
* @return the thread holding a lock, or
* null if there is none
* @throws NullPointerException
* if the object is null
*/
public static Thread getLockingThread( final Object object )
{
if ( object == null )
throw new NullPointerException( "Null object" );
final long identity = System.identityHashCode( object );
final Thread[] allThreads = getAllThreads( );
ThreadInfo info = null;
MonitorInfo[] monitors = null;
for ( Thread thread : allThreads )
{
info = getThreadInfo( thread.getId( ) );
if ( info == null )
continue;
monitors = info.getLockedMonitors( );
for ( MonitorInfo monitor : monitors )
if ( identity == monitor.getIdentityHashCode( ) )
return thread;
}
return null;
}