वर्तमान में जावा में चल रहे सभी थ्रेड्स की सूची प्राप्त करें


232

क्या कोई तरीका है जिससे मुझे वर्तमान जेवीएम ( मेरी कक्षा द्वारा शुरू नहीं किए गए धागे सहित ) में सभी चल रहे थ्रेड्स की एक सूची मिल सकती है ?

क्या सूची में सभी थ्रेड्स की वस्तुओं Threadऔर Classवस्तुओं को प्राप्त करना संभव है ?

मैं कोड के माध्यम से ऐसा करने में सक्षम होना चाहता हूं।

जवाबों:


325

एक चलने योग्य सेट प्राप्त करने के लिए:

Set<Thread> threadSet = Thread.getAllStackTraces().keySet();

19
जबकि अन्य वैकल्पिक प्रस्तावित की तुलना में बहुत साफ है, यह सभी धागे के लिए स्टैक निशान प्राप्त करने की लागत को कम करने का नकारात्मक पक्ष है। यदि आप वैसे भी उन स्टैक के निशान का उपयोग कर रहे हैं, तो यह स्पष्ट रूप से बेहतर है। यदि नहीं, तो यह साफ कोड के अलावा कोई लाभ नहीं होने के लिए काफी धीमा हो सकता है।
एडी

29
@Eddie क्या यह सामान्य ज्ञान से एक धारणा है, या आपने प्रयोग किए हैं? "काफी धीमी" आप कहते हैं; कितना धीमा है? यह इसके लायक है? मैं दक्षता के लिए कोड को बदतर बनाने के किसी भी प्रयास पर सवाल उठाता हूं। यदि आपके पास दक्षता की आवश्यकता है और मात्रात्मक रूप से दक्षता को मापने के लिए एक बुनियादी ढांचा है, तो मैं कोड को बदतर बनाने वाले लोगों के साथ ठीक हूं, क्योंकि वे जानते हैं कि वे क्या कर रहे हैं। डोनाल्ड नथ के अनुसार सभी बुराई की जड़ देखें ।
thejoshwolfe

20
मैंने इन विशिष्ट विकल्पों को समयबद्ध नहीं किया है, लेकिन मैंने थ्रेड्स की एक सूची बनाम ढेर के निशान को इकट्ठा करने के अन्य जावा साधनों के साथ काम किया है। प्रदर्शन प्रभाव बहुत दृढ़ता से निर्भर करता है जिस पर JVM आप उपयोग कर रहे हैं (उदाहरण के लिए JRockit बनाम Sun JVM)। यह आपके विशिष्ट उदाहरण में मापने लायक है। यह प्रभावित करेगा या नहीं, यह आपकी जेवीएम पसंद पर निर्भर करता है और आपके पास कितने धागे हैं। मैंने पाया कि लगभग 250 थ्रेड्स के लिए थ्रेडएक्सएक्सबीएन डंपएप्लॉट्स के माध्यम से सभी स्टैक निशान प्राप्त करने के लिए 150 - 200 मिसेक लेते हैं, जबकि थ्रेड्स की सूची (बिना निशान) प्राप्त करने के लिए औसत दर्जे का (0 मिसेक) नहीं होना चाहिए।
एडी

4
मेरे सिस्टम पर (ओरेकल जावा 1.7 वीएम), एक त्वरित जांच से पता चलता है कि यह विधि नीचे के विकल्प की तुलना में ~ 70..80 गुना अधिक है। ढेर के निशान और प्रतिबिंब सबसे भारी जावा ऑपरेशन के हैं।
फ्रांज डी।

5
@Thejoshwolfe: बेशक, पठनीयता एक महत्वपूर्ण कारक है, और किसी को माइक्रो-ऑप्टिमाइज़ेशन आदि नहीं करना चाहिए। हालांकि, मैंने एक छोटे से अनुप्रयोग प्रदर्शन मॉनिटर को लिखते हुए अपना शोध किया। इस तरह के टूल के लिए, विश्वसनीय डेटा प्राप्त करने के लिए एक न्यूनतम प्रदर्शन छाप आवश्यक है, इसलिए मैंने स्टैकट्रेस-कम विधि को चुना।
फ्रांज डी।

75

ThreadGroupइस तरह से रूट को हैंडल करें:

ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parentGroup;
while ((parentGroup = rootGroup.getParent()) != null) {
    rootGroup = parentGroup;
}

अब, enumerate()फ़ंक्शन को रूट समूह पर बार-बार कॉल करें । दूसरा तर्क आपको सभी सूत्र प्राप्त करने देता है, पुनरावर्ती:

Thread[] threads = new Thread[rootGroup.activeCount()];
while (rootGroup.enumerate(threads, true ) == threads.length) {
    threads = new Thread[threads.length * 2];
}

ध्यान दें कि हम सभी प्रविष्टियों को शामिल करने के लिए सरणी के बड़े होने तक बार-बार एन्यूमरेट () को कैसे कहते हैं।


22
मैं हैरान हूं कि यह रणनीति इंटरनेट पर इतनी लोकप्रिय है। मेरी रणनीति तरीका सरल है (कोड की 1 पंक्ति) और दौड़ की स्थिति से बचने के अतिरिक्त बोनस के साथ ही काम करता है।
thejoshwolfe

11
@Thejoshwolfe: असल में, मैं सहमत हूँ - मुझे लगता है कि आपका उत्तर बहुत बेहतर है, और यह शायद पहली बार में स्वीकृत उत्तर होता अगर एक साल देर नहीं होती। यदि ओपी अभी भी एसओ को आवृत्त करता है, जो वह स्पष्ट रूप से करता है, तो उसे मेरे उत्तर को स्वीकार न करने की सलाह दी जाएगी।
फ्राइरिच राबे

2
ध्यान दें कि इसके अलावा किसी भी चीज़ के लिए rootGroup, आपको उपयोग करना चाहिए new Thread[rootGroup.activeCount()+1]activeCount()शून्य हो सकता है, और अगर यह आप एक अनंत लूप में चलेगा।
jmiserez

7
@Thejoshwolfe मुझे लगता है कि यह समाधान बहुत कम महंगा है।
हाओहजुन

19
इस अंडररेटेड उत्तर के लिए +1, क्योंकि यह मॉनिटरिंग उद्देश्यों के लिए बहुत अधिक अनुकूल है। निगरानी में इसकी अंतर्निहित दौड़ की स्थिति ज्यादा मायने नहीं रखती है। हालांकि, जैसा कि कुछ क्विक'डीनहाइट टेस्ट से पता चला है, यह स्टैकट्रेस-आधारित समाधान की तुलना में लगभग 70-80 गुना अधिक तेज है। निगरानी के लिए, एक छोटा प्रदर्शन छाप आवश्यक है, जैसा कि आप निगरानी प्रणाली पर प्रभावों को यथासंभव छोटा रखना चाहते हैं (हाइजेनबर्ग फिर से हमला करता है :) डिबगिंग के लिए, जहां आपको अधिक विश्वसनीय जानकारी की आवश्यकता हो सकती है, स्टैकट्रेस विधि हो सकती है आवश्यक। BTW, MxBean समाधान स्टैकट्रैक्स का उपयोग करने की तुलना में भी धीमा है।
फ्रांज डी।

29

हाँ, देख लेना धागे की एक सूची प्राप्त करने । उस पेज पर बहुत सारे उदाहरण।

यह प्रोग्रामेटिक रूप से करना है। यदि आप कम से कम लिनक्स पर एक सूची चाहते हैं तो आप केवल इस कमांड का उपयोग कर सकते हैं:

kill -3 processid

और VM stdout को थ्रेड डंप करेगा।


5
मारना -3? कम से कम मेरे लिनक्स पर, वह "टर्मिनल लीव" है। मारता है, सूची नहीं देता।
माइकल एच।

5
क्लेटस वास्तव में सही है - एक किल -3 स्टडआउट को डंप करेगा, भले ही संकेत का मतलब क्या हो। मैं इसके बजाय jstack का उपयोग करने पर विचार करूंगा।
डैन हार्डिकर

थ्रेड्स की एक सूची प्राप्त नहीं की जा सकती है: nadeausoftware.com ने कनेक्ट करने से इनकार कर दिया।
DSlomer64


14

क्या आपने jconsole पर एक नज़र डाली है ?

यह एक विशेष जावा प्रक्रिया के लिए चलने वाले सभी थ्रेड्स को सूचीबद्ध करेगा।

आप JDK बिन फ़ोल्डर से jconsole शुरू कर सकते हैं।

आप Ctrl+Breakविंडोज में या kill pid --QUITलिनक्स में भेजकर सभी थ्रेड्स के लिए एक पूर्ण स्टैक ट्रेस प्राप्त कर सकते हैं ।


मैं अपने जावा वर्ग के भीतर सूची का उपयोग करना चाहता हूं
Kryten

किस मामले में क्लेटस के उत्तर को देखें।
पीपीज

3
उम, लोग इसे क्यों वोट दे रहे हैं जब आदमी ने कहा कि वह एक प्रोग्रामेटिक समाधान चाहता था?
cletus

क्योंकि सवाल यह नहीं बताता है। मैं प्रश्न को स्पष्ट करने के लिए संपादित करूँगा।
pjp

8

Apache Commons यूजर्स इस्तेमाल कर सकते हैं ThreadUtils। वर्तमान कार्यान्वयन वॉक थ्रेड समूह दृष्टिकोण का उपयोग करता है जो पहले उल्लिखित है।

for (Thread t : ThreadUtils.getAllThreads()) {
      System.out.println(t.getName() + ", " + t.isDaemon());
}

7

आप कुछ इस तरह की कोशिश कर सकते हैं:

Thread.getAllStackTraces().keySet().forEach((t) -> System.out.println(t.getName() + "\nIs Daemon " + t.isDaemon() + "\nIs Alive " + t.isAlive()));

और आप स्पष्ट रूप से अधिक धागा विशेषता प्राप्त कर सकते हैं यदि आप की जरूरत है।


5

में ग्रूवी आप निजी तरीकों कॉल कर सकते हैं

// Get a snapshot of the list of all threads 
Thread[] threads = Thread.getThreads()

में जावा , आपके द्वारा दी गई सुरक्षा प्रबंधक यह अनुमति देता है कि विधि का उपयोग प्रतिबिंब आह्वान कर सकते हैं।


मुझे त्रुटि मिलती है, थ्रेड के लिए परिभाषित नहीं किया जाता है। और मैं इस फ़ंक्शन को प्रलेखन में नहीं देखता।

4

मुख्य धागे द्वारा शुरू किए गए धागे की सूची प्राप्त करने के लिए कोड स्निपेट:

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

3
    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 + "  ");
        }
    }

3

जावा कंसोल में, Ctrl- तोड़ मारा । यह सभी थ्रेड्स को सूचीबद्ध करेगा और ढेर के बारे में कुछ जानकारी देगा। यह आपको पाठ्यक्रम की वस्तुओं तक पहुंच प्रदान नहीं करेगा। लेकिन यह वैसे भी डिबगिंग के लिए बहुत मददगार हो सकता है।


1

टर्मिनल का उपयोग करते हुए थ्रेड्स और उनके पूर्ण राज्यों की सूची प्राप्त करने के लिए, आप नीचे दिए गए कमांड का उपयोग कर सकते हैं:

jstack -l <PID>

PID आपके कंप्यूटर पर चलने वाली प्रक्रिया की id है। अपने जावा प्रक्रिया की प्रक्रिया आईडी प्राप्त करने के लिए आप बस चला सकते हैंjps कमांड ।

इसके अलावा, आप अपने धागा डंप कि TDAs में jstack (थ्रेड डंप विश्लेषक) इस तरह के द्वारा उत्पादित विश्लेषण कर सकते हैं fastthread या Spotify धागा विश्लेषक उपकरण


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.