Jawaban:
Untuk mendapatkan perangkat yang dapat diubah:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
Dapatkan pegangan ke root ThreadGroup
, seperti ini:
ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parentGroup;
while ((parentGroup = rootGroup.getParent()) != null) {
rootGroup = parentGroup;
}
Sekarang, panggil enumerate()
fungsi pada grup root berulang kali. Argumen kedua memungkinkan Anda mendapatkan semua utas, secara rekursif:
Thread[] threads = new Thread[rootGroup.activeCount()];
while (rootGroup.enumerate(threads, true ) == threads.length) {
threads = new Thread[threads.length * 2];
}
Perhatikan bagaimana kami memanggil enumerate () berulang kali hingga array cukup besar untuk memuat semua entri.
rootGroup
, Anda harus menggunakan new Thread[rootGroup.activeCount()+1]
. activeCount()
bisa menjadi nol, dan jika itu Anda akan mengalami loop tak terbatas.
Ya, lihatlah untuk mendapatkan daftar utas . Banyak contoh di halaman itu.
Itu untuk melakukannya secara terprogram. Jika Anda hanya ingin daftar di Linux setidaknya Anda bisa menggunakan perintah ini:
kill -3 processid
dan VM akan melakukan thread dump ke stdout.
Anda bisa mendapatkan banyak informasi tentang utas dari ThreadMXBean .
Panggil metode ManagementFactory.getThreadMXBean () statis untuk mendapatkan referensi ke MBean.
Apakah Anda sudah melihat jconsole ?
Ini akan mencantumkan semua utas yang berjalan untuk proses Java tertentu.
Anda dapat memulai jconsole dari folder bin JDK.
Anda juga bisa mendapatkan jejak tumpukan penuh untuk semua utas dengan menekan Ctrl+Break
di Windows atau dengan mengirim kill pid --QUIT
di Linux.
Pengguna Apache Commons dapat digunakan ThreadUtils
. Implementasi saat ini menggunakan pendekatan walk the thread group yang telah diuraikan sebelumnya.
for (Thread t : ThreadUtils.getAllThreads()) {
System.out.println(t.getName() + ", " + t.isDaemon());
}
Di Groovy Anda dapat memanggil metode pribadi
// Get a snapshot of the list of all threads
Thread[] threads = Thread.getThreads()
Di Jawa , Anda bisa memanggil metode itu menggunakan refleksi asalkan manajer keamanan mengizinkannya.
Cuplikan kode untuk mendapatkan daftar utas dimulai oleh utas utama:
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();
}
}
}
keluaran:
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
Jika Anda memerlukan semua utas termasuk utas sistem, yang belum dimulai oleh program Anda, hapus kondisi di bawah ini.
if ( t.getThreadGroup() == Thread.currentThread().getThreadGroup())
Sekarang output:
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 + " ");
}
}
Untuk mendapatkan daftar utas dan status lengkapnya menggunakan terminal, Anda dapat menggunakan perintah di bawah ini:
jstack -l <PID>
PID mana yang merupakan id proses yang berjalan di komputer Anda. Untuk mendapatkan id proses dari proses java Anda, Anda cukup menjalankan jps
perintah.
Selain itu, Anda dapat menganalisis dump thread Anda yang dihasilkan oleh jstack di TDA (Thread Dump Analyzer) seperti alat penganalisa benang fastthread atau spotify .