回答:
反復可能なセットを取得するには:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
次のThreadGroup
ように、rootへのハンドルを取得します。
ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parentGroup;
while ((parentGroup = rootGroup.getParent()) != null) {
rootGroup = parentGroup;
}
ここでenumerate()
、ルートグループの関数を繰り返し呼び出します。2番目の引数では、すべてのスレッドを再帰的に取得できます。
Thread[] threads = new Thread[rootGroup.activeCount()];
while (rootGroup.enumerate(threads, true ) == threads.length) {
threads = new Thread[threads.length * 2];
}
配列がすべてのエントリを格納するのに十分な大きさになるまで、enumerate()を繰り返し呼び出す方法に注意してください。
rootGroup
、を使用する必要があることに注意してくださいnew Thread[rootGroup.activeCount()+1]
。activeCount()
ゼロになる可能性があり、ゼロの場合は無限ループに陥ります。
はい、スレッドのリストの取得をご覧ください。そのページにはたくさんの例があります。
それはプログラムで行うことです。少なくともLinuxのリストが必要な場合は、次のコマンドを使用できます。
kill -3 processid
VMはstdoutにスレッドダンプを実行します。
あなたはからスレッドに関する多くの情報を得ることができますThreadMXBean。
静的ManagementFactory.getThreadMXBean()メソッドを呼び出して、MBeanへの参照を取得します。
あなたは見てとったJConsoleの?
これにより、特定のJavaプロセスで実行されているすべてのスレッドがリストされます。
jconsoleはJDK binフォルダーから起動できます。
Ctrl+Break
Windowsでヒットするかkill pid --QUIT
、Linuxで送信することにより、すべてのスレッドの完全なスタックトレースを取得することもできます。
Apache Commonsユーザーはを使用できますThreadUtils
。現在の実装では、前述のウォークスレッドグループアプローチを使用しています。
for (Thread t : ThreadUtils.getAllThreads()) {
System.out.println(t.getName() + ", " + t.isDaemon());
}
メインスレッドによって開始されたスレッドのリストを取得するコードスニペット:
import java.util.Set;
public class ThreadSet {
public static void main(String args[]) throws Exception{
Thread.currentThread().setName("ThreadSet");
for ( int i=0; i< 3; i++){
Thread t = new Thread(new MyThread());
t.setName("MyThread:"+i);
t.start();
}
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for ( Thread t : threadSet){
if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup()){
System.out.println("Thread :"+t+":"+"state:"+t.getState());
}
}
}
}
class MyThread implements Runnable{
public void run(){
try{
Thread.sleep(5000);
}catch(Exception err){
err.printStackTrace();
}
}
}
出力:
Thread :Thread[MyThread:2,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:0,5,main]:state:TIMED_WAITING
Thread :Thread[MyThread:1,5,main]:state:TIMED_WAITING
Thread :Thread[ThreadSet,5,main]:state:RUNNABLE
プログラムによって開始されていない、システムスレッドを含むすべてのスレッドが必要な場合は、以下の条件を削除してください。
if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup())
今出力:
Thread :Thread[MyThread:2,5,main]:state:TIMED_WAITING
Thread :Thread[Reference Handler,10,system]:state:WAITING
Thread :Thread[MyThread:1,5,main]:state:TIMED_WAITING
Thread :Thread[ThreadSet,5,main]:state:RUNNABLE
Thread :Thread[MyThread:0,5,main]:state:TIMED_WAITING
Thread :Thread[Finalizer,8,system]:state:WAITING
Thread :Thread[Signal Dispatcher,9,system]:state:RUNNABLE
Thread :Thread[Attach Listener,5,system]:state:RUNNABLE
public static void main(String[] args) {
// Walk up all the way to the root thread group
ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parent;
while ((parent = rootGroup.getParent()) != null) {
rootGroup = parent;
}
listThreads(rootGroup, "");
}
// List all threads and recursively list all subgroup
public static void listThreads(ThreadGroup group, String indent) {
System.out.println(indent + "Group[" + group.getName() +
":" + group.getClass()+"]");
int nt = group.activeCount();
Thread[] threads = new Thread[nt*2 + 10]; //nt is not accurate
nt = group.enumerate(threads, false);
// List every thread in the group
for (int i=0; i<nt; i++) {
Thread t = threads[i];
System.out.println(indent + " Thread[" + t.getName()
+ ":" + t.getClass() + "]");
}
// Recursively list all subgroups
int ng = group.activeGroupCount();
ThreadGroup[] groups = new ThreadGroup[ng*2 + 10];
ng = group.enumerate(groups, false);
for (int i=0; i<ng; i++) {
listThreads(groups[i], indent + " ");
}
}