/** * Copyright 2008, David Robert Nadeau, NadeauSoftware.com * * This file is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2 of * the License, or (at your option) any later version. * * This file 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this file. If not, see * <a href="http://www.gnu.org/licenses">GNU Licenses</a>. */ import java.lang.management.*; /** * The ThreadUtilities class provides a collection of static methods * for listing and finding Thread, ThreadGroup, and ThreadInfo objects. * <p> * Please see the accompanying article: * <a href="http://nadeausoftware.com/articles/2008/04/java_tip_how_list_and_find_threads_and_thread_groups">Java tip: How to list and find threads and thread groups</a> * * @author <a href="http://NadeauSoftware.com/">David R. Nadeau</a> */ public final class ThreadUtilities { // Dummy constructor /** * The ThreadUtilities class cannot be instanced. */ private ThreadUtilities( ) { } // Thread groups /** * The root thread group saved on the first search for it. * The root group doesn't change for the life of the JVM, * so once found there is no need to find it again. */ private static ThreadGroup rootThreadGroup = null; /** * Get the root thread group in the thread group tree. * Since there is always a root thread group, this * method never returns null. * * @return the root thread group */ public static ThreadGroup getRootThreadGroup( ) { if ( rootThreadGroup != null ) return rootThreadGroup; ThreadGroup tg = Thread.currentThread( ).getThreadGroup( ); ThreadGroup ptg; while ( (ptg = tg.getParent( )) != null ) tg = ptg; rootThreadGroup = tg; return tg; } /** * Get a list of all thread groups. Since there is * always at least one thread group (the root), this * method never returns a null or empty array. * * @return an array of thread groups */ public static ThreadGroup[] getAllThreadGroups( ) { final ThreadGroup root = getRootThreadGroup( ); int nAlloc = root.activeGroupCount( ); int n = 0; ThreadGroup[] groups = null; do { nAlloc *= 2; groups = new ThreadGroup[ nAlloc ]; n = root.enumerate( groups, true ); } while ( n == nAlloc ); ThreadGroup[] allGroups = new ThreadGroup[n+1]; allGroups[0] = root; System.arraycopy( groups, 0, allGroups, 1, n ); return allGroups; } /** * Get the thread group with the given name. A null is * returned if no such group is found. If more than one * group has the same name, the first one found is returned. * * @param name the thread group name to search for * @return the thread group, or null if not found * @throws NullPointerException * if the name is null */ public static ThreadGroup getThreadGroup( final String name ) { if ( name == null ) throw new NullPointerException( "Null name" ); final ThreadGroup[] groups = getAllThreadGroups( ); for ( ThreadGroup group : groups ) if ( group.getName( ).equals( name ) ) return group; return null; } // Threads /** * Get a list of all threads. Since there is always at * least one thread, this method never returns null or * an empty array. * * @return an array of threads */ public static Thread[] getAllThreads( ) { final ThreadGroup root = getRootThreadGroup( ); final ThreadMXBean thbean = ManagementFactory.getThreadMXBean( ); int nAlloc = thbean.getThreadCount( ); int n = 0; Thread[] threads = null; do { nAlloc *= 2; threads = new Thread[ nAlloc ]; n = root.enumerate( threads, true ); } while ( n == nAlloc ); return java.util.Arrays.copyOf( threads, n ); } /** * Get a list of all threads in a thread group. An empty * array is returned if there are no threads in the group. * * @param group the thread group to list * @return an array of threads * @throws NullPointerException * if the group is null */ public static Thread[] getGroupThreads( final ThreadGroup group ) { if ( group == null ) throw new NullPointerException( "Null group" ); int nAlloc = group.activeCount( ); int n = 0; Thread[] threads = null; do { nAlloc *= 2; threads = new Thread[ nAlloc ]; n = group.enumerate( threads, false ); } while ( n == nAlloc ); return java.util.Arrays.copyOf( threads, n ); } /** * Get a list of all threads in a named thread group. * A null is returned if the group cannot be found. * An empty array is returned if there are no threads in * the group. * * @param name the name of the thread group * @return an array of threads, or null if the * group is not found * @throws NullPointerException * if the name is null */ public static Thread[] getGroupThreads( final String name ) { final ThreadGroup group = getThreadGroup( name ); if ( group == null ) return null; return getGroupThreads( group ); } /** * Get a list of all threads, sorted from highest to * lowest priority. Since there is always at least one * thread, this method never returns null or an empty * array. Since threads may change their priority during * this method's sort, the returned thread list may not be * correct by the time it is returned. * * @return an array of threads */ public static Thread[] getAllThreadsPrioritized( ) { final Thread[] allThreads = getAllThreads( ); java.util.Arrays.sort( allThreads, new java.util.Comparator<Thread>( ) { public int compare( final Thread t1, final Thread t2 ) { return t2.getPriority( ) - t1.getPriority( ); } } ); return allThreads; } /** * 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; } /** * Get the thread who's lock is blocking the given thread. * A null is returned if there is no such thread. * * @param blockedThread the blocked thread * @return the blocking thread, or null if * there is none * @throws NullPointerException * if the blocked thread is null */ public static Thread getBlockingThread( final Thread blockedThread ) { final ThreadInfo info = getThreadInfo( blockedThread ); if ( info == null ) return null; final long id = info.getLockOwnerId( ); if ( id == -1 ) return null; return getThread( id ); } }
http://nadeausoftware.com/articles/2008/04/java_tip_how_list_and_find_threads_and_thread_groups
相关推荐
在Java编程中,多线程查询数据库是一种常见的优化策略,特别是在处理大数据量或者需要并行执行多个查询时。本文将详细探讨如何利用Java的多线程技术和线程池来实现并发查询数据库,以及相关的文件`BatchDataUtil....
本文将深入探讨Java线程停止的方法,特别是通过一个示例代码片段来解析如何利用标志变量(Flag)控制线程的生命周期,以及这种方法背后的原理与最佳实践。 ### Java线程停止方法概述 在Java中,直接调用线程的`...
线程堆栈是Java虚拟机在某一时刻对所有活动线程的状态快照,包括线程ID、线程状态、调用堆栈等信息。当应用程序出现性能问题或疑似死锁时,开发者通常会使用`jstack`命令来生成线程堆栈,这是一个内置在JDK中的...
Java多线程笔记是 Java 编程语言中关于多线程编程的笔记,涵盖了线程基础知识、线程优先级、线程状态、守护线程、构造线程、线程中断等多方面的内容。 获取简单 main 程序中的线程 在 Java 中,可以使用 ...
Java自定义线程模型在软件开发中扮演着重要的角色,特别是在高性能、高并发的应用场景,如游戏服务器。本文将深入探讨如何在Java中构建自定义线程模型,并分享一些实践经验。 首先,我们要明白为什么要自定义线程...
在分析Java应用程序的性能问题时,了解和分析Java线程的状态是非常关键的。线程堆栈信息可以让我们深入观察到线程的运行状况,包括线程的当前状态、调用堆栈、锁信息等。为了获取这些信息,我们可以使用jstack工具,...
在Java编程领域,多线程技术是实现并发执行任务的关键工具,尤其在处理实时系统如银行转账交易时显得尤为重要。银行转账涉及到多个账户之间的资金流动,这种操作通常需要高效、安全且并发地进行。本项目"java多线程...
Java多线程文件分片下载实现的示例代码 本文将详细介绍Java多线程文件分片下载的实现示例代码,通过示例代码,大家可以学习和理解多线程文件分片下载的技术难点和解决方案。 多线程下载的技术难点 ---------------...
通过这个接口,我们可以获取线程的各种信息,包括线程ID、线程名称、线程状态等。线程状态主要有以下几种: 1. 新建(NEW):线程被创建但尚未启动。 2. 可运行(RUNNABLE):线程正在Java虚拟机中执行。 3. 阻塞...
这是启动Java线程的标准方式。 其他如`getThreadID()`等方法提供了对线程ID的访问,这些方法通常用于获取和设置线程的相关信息。 在实际应用中,这样的设计可以用来构建一个线程调度框架,根据线程间的依赖关系...
核心逻辑出现在splitList()方法中,该方法根据每个线程需要处理的用户数(示例中为2个用户),将用户列表分割成若干个子列表。每个子列表就是一个线程需要处理的用户数据。splitList()方法通过计算页数和页码的方式...
Java多线程聊天室是一个基于Java编程语言实现的实时通讯应用,主要利用了Java的多线程技术来处理并发用户间的交互。在这个项目中,我们可以深入理解Java的并发编程概念,以及如何在实际应用中应用这些知识。以下将...
QQ界面的聊天系统,服务器端用多线程实现了公共聊天和私人聊天,还可以传送简单的文本文档 说明: 主程序:SFace.java和Face.java 服务器端操作说明: 1、输入本地IP和聊天通信的端口,然后建立服务器; 2、消息...
【Java会话管理与多线程详解】 Java会话管理主要涉及的是在Web应用程序中如何维护用户的状态信息。在Web应用中,用户打开一个页面,然后进行一系列操作,这些操作可能跨越多个HTTP请求。为了保持用户的上下文信息,...
echo "Java 进程未找到,无法收集线程信息。" exit 1 fi # 使用jstack收集线程信息 echo "线程信息收集于 $TIMESTAMP:" >> $LOG_FILE jstack $JAVA_PID >> $LOG_FILE # 输出成功信息 echo "线程信息已成功记录到...
一个标准的线程由线程ID、当前指令指针(PC)、寄存器集合和堆栈组成。在多线程环境中,这些线程可以并行执行,提高程序的执行效率。线程的主要优点是可以将一个进程的资源分配和执行调度分开,使各个线程既可以共享...
本程序是在原有基础上逐步完善的,第一版:...详细文档请看: http://www.open-open.com/home/space.php?uid=183&do=blog&id=8799 本程序很适合在主机间批量传输文件和目录,参数可控
除了`ThreadPoolExecutor`,Java还提供了`Executors`工具类,它提供了一些预设的线程池配置,如`newFixedThreadPool`(固定大小线程池)、`newSingleThreadExecutor`(单线程线程池)等,方便开发者快速创建线程池。...
"java自动生成id策略"指的是设计并实现一种机制,确保在多线程环境下能够高效、唯一地生成ID。这里我们将详细探讨这个主题,以及如何根据描述实现这样的策略。 首先,ID的生成通常要求满足以下条件: 1. 唯一性:...
每个线程独立运行,根据各自的逻辑进行生产或消费操作。 这个例子展示了Java多线程如何解决并发问题,尤其是通过 `wait()` 和 `notifyAll()` 方法实现线程间的同步与通信。此外,它也演示了如何使用 `Runnable` ...