2011-12-29 10 views
27

हाइपोटेटिकल परिदृश्य:
मेरे पास कुछ I/O, मुख्य थ्रेड खत्म और रिटर्न के लिए जिम्मेदार एक डिमन थ्रेड है, और JVM मेरे डिमन थ्रेड को समाप्त करने का निर्णय लेता है।जेवीएम डिमन थ्रेड को कैसे समाप्त करता है? या डेमॉन थ्रेड कैसे लिखें जो

ऐसा कैसे करता है? बीच में? अंतिम रूप? मैं अपने डेमॉन थ्रेड को कैसे कोड कर सकता हूं ताकि जब इसे समाप्त किया जाए तो यह शानदार ढंग से प्रतिक्रिया करता है?

+1

क्या आपने सोर्सकोड देखा था? –

+2

@StephenC यह मेरे लिए नहीं हुआ था, और निश्चित रूप से एक निश्चित उत्तर प्राप्त करेगा (हालांकि _necessarily_ उपयोगी नहीं है)। मैं व्यक्तिगत रूप से, हालांकि, कोशिश करने के लिए पर्याप्त बहादुर नहीं हूं और वास्तव में किसी और की अपेक्षा नहीं करता हूं। –

+0

ठीक है, मुझे और अधिक स्पष्ट होने दें। इस तरह के किसी प्रश्न का उत्तर देने का सबसे अच्छा तरीका स्रोत कोड, या कम से कम जावा कोड को देखना है। आम तौर पर यह पढ़ना आसान है और अच्छी तरह से टिप्पणी की है।(और मैं समझता हूँ कि कैसे एक प्रश्न के एक निश्चित जवाब एक गैर निश्चित एक से कम उपयोगी है असफल ... खासकर अगर * यदि आप व्यक्ति कोड को पढ़ने! * थे) –

उत्तर

10

मैं सिर्फ एक परीक्षण के रूप में निम्नलिखित कोड लिखा है:

public class DaemonThreadPlay { 
    public static void main(String [] args) { 
     Thread daemonThread = new Thread() { 
      public void run() { 
       while (true) { 
        try { 
         System.out.println("Try block executed"); 
         Thread.sleep(1000l); 
        } catch (Throwable t) { 
         t.printStackTrace(); 
        } 
       } 
      } 

      @Override 
      public void finalize() { 
       System.out.println("Finalize method called"); 
      } 
     }; 
     daemonThread.setDaemon(true); 
     daemonThread.start(); 

     try { 
      Thread.sleep(2500l); 
     } catch (Throwable t) { 
      //NO-OP 
     } 
    } 
}  

मैं डेमॉन धागे की पकड़ ब्लॉक में और अंतिम रूप देने विधि में breakpoints डाल दिया। कोशिश ब्लॉक को निष्पादित किए जाने के बावजूद ब्रेकपॉइंट तक पहुंचा नहीं गया था। जाहिर है इस कोड में सिंक्रनाइज़ेशन/टाइमिंग समस्याएं हैं, लेकिन मुझे लगता है कि हम सुरक्षित रूप से निष्कर्ष निकाल सकते हैं कि शटडाउन पर डिमन थ्रेड बाधित नहीं होते हैं और न ही उनके अंतिम() विधियों को जरूरी रूप से लागू किया जाता है।

तुम हमेशा JVM रनटाइम करने के लिए एक बंद हुक जोड़ सकते हैं:

Thread shutdownHook = ... // construct thread that somehow 
          // knows about all the daemon threads 
Runtime.getRuntime().addShutdownHook(shutdownHook); 

आपका बंद हुक स्पष्ट रूप से जो कुछ भी कार्य एक "सुंदर" शट डाउन के लिए आवश्यक हैं कर सकते हैं।

+1

मुझे शट डाउन हुक पसंद है। –

+0

मिले [इस] (http://stackoverflow.com/questions/1323408/get-a-list-of-all-threads-currently-running-in-java/3018672#3018672) जब तरीके सक्रिय सूत्र प्राप्त करने के लिए की तलाश में । कम से कम एक उपयोगकर्ता थ्रेड की जांच करने के लिए सरणी पर पुनरावृत्ति करना होगा।
मुझे लगता है कि एक बंद हुक सबसे अच्छा समाधान है, कभी नहीं इस कार्यक्षमता के बारे में पहले से जानता था। मुझे लगता है कि मैं अपने मुख्य वर्ग में अपने शट डाउन हुक का संदर्भ रखूंगा, और शटडाउन हुक में अपने डिमन थ्रेड का संग्रह रखूंगा। तो मैं बस उन सभी को बाधित कर सकता हूं। एक बार जब मैं इसे लागू करता हूं तो मैं अपना कोड पोस्ट करने की कोशिश करूंगा। –

+2

यदि आप फोन 'System.gc()' स्पष्ट रूप से और JVM विकल्प '-XX: + DisableExplicitGC' सेट नहीं है, तो डेमॉन धागा बाहर निकल जाएगा। इसका मतलब है कि कचरा कलेक्टर सभी उपयोगकर्ता धागे खत्म होने के बाद डेमॉन थ्रेड को बंद करने के लिए ज़िम्मेदार है। – George

4

AFAIK, डेमॉन धागे मुख्य धारा I/O काम के लिए वास्तव में नहीं हैं। यदि सभी धागे पूरे हो गए हैं, तो JVM अचानक सभी डिमन थ्रेड बंद कर सकता है। शटडाउन हुक से

ExecutorService execPool = Executors.newSingleThreadExecutor(new ThreadFactory() { 

    @Override  
    public Thread newThread(Runnable runnable) {  
     Thread thread = Executors.defaultThreadFactory().newThread(runnable); 
     thread.setDaemon(true); 
     return thread;  
    } 
}); 

आह्वान executorservice बंद विधि: आपकी आवश्यकता के लिए चारों ओर संभव काम नीचे की तरह एक ExecutorService बनाने होगा।

Runtime.getRuntime().addShutdownHook(....) 
+0

आपकी नई थ्रेड विधि वास्तव में हर बार एक नया थ्रेड फैक्ट्री बनाती है। 'Executors.defaultThreadFactory के लिए एक कॉल()' सिर्फ एक 'नई DefaultThreadFactory()' – benez

1

उपयोग बाधा और शामिल होने:

class Daemon extends Thread { 
    public void run() { 
     while (true) { 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       System.out.println(e); 
       break; 
      } 
     } 
     System.out.println("exit run()"); 
    } 
} 
public class So8663107 { 
    public static void main(String[] arguments) throws InterruptedException { 
     System.out.println(Thread.activeCount()); 
     Daemon daemon = new Daemon(); 
     daemon.setDaemon(true); 
     daemon.start(); 
     Thread.sleep(2500); 
     System.out.println(Thread.activeCount()); 
     daemon.interrupt(); 
     daemon.join(); 
     System.out.println(Thread.activeCount()); 
    } 
} 
+3

मुझे नहीं लगता कि आप सवाल समझ में आ देता है। मैं अपने डेमन थ्रेड को बाधित नहीं करना चाहता हूं। मैं जानना चाहता हूं कि JVM उन्हें कैसे समाप्त करता है, और इससे कैसे निपटें। –

+0

क्षमा करें, मैं जवाब देने का प्रयास कर रहा था: "मैं अपने डिमन थ्रेड को कैसे कोड कर सकता हूं ताकि यह शानदार तरीके से समाप्त हो सके?" –

+0

ठीक है, मैं सवाल –

5

मुझे लगता है कि आप गलत क्या एक डेमॉन धागा है।

देखें what is a daemon thread in java

सारांश में, यह मूल रूप से मतलब है कि एक डेमॉन धागा किसी भी आई/ओ कर नहीं किया जाना चाहिए या किसी संसाधनों पकड़े। यदि आप इस मूल नियम का उल्लंघन कर रहे हैं तो आपका धागा डेमॉन थ्रेड होने योग्य नहीं है।

शटडाउन हुक जोड़ना आपके कोड को JVM समाप्ति से पहले सुनिश्चित करने का मानक तरीका है, लेकिन यह 100% गारंटी नहीं है - आपका जेवीएम उदाहरण के लिए क्रैश हो सकता है, जिससे ओएस को संसाधनों को व्यवस्थित करने के लिए छोड़ दिया जा सकता है जो ओएस की रक्षा करता है, लेकिन संभवतः आपके आवेदन को असंगत/गलत स्थिति में छोड़ देता है।

सिस्टम चेकपॉइंटिंग और रिकवरी तंत्र सॉफ़्टवेयर के प्रारंभिक दिनों (उदाहरण के लिए ऑपरेटिंग सिस्टम और बैच ऑपरेशंस) पर वापस जाते हैं, और दुर्भाग्यवश, यह पहिया फिर से आविष्कार कर रहा है क्योंकि कोई "चांदी बुलेट" दृष्टिकोण (एपीआई) नहीं है जो tackles एक सामान्य पर्याप्त तरीके से यह समस्या।

+0

क्या दावा है कि Daemon धागे आईओ नहीं करना चाहिए या संसाधनों के आयोजन के लिए आधार है संपादित कर लिया है? – ykaganovich

+0

दिए गए लिंक का पालन करें और आपको कुछ अंतर्दृष्टि मिलेंगी। – user924272

+1

क्षमा करें, मैं असहमत हूं। जब तक यह समझा जाता है कि डेमॉन थ्रेड को मध्य-प्रसंस्करण में मार दिया जा सकता है, तब तक कोई खतरा नहीं है, जब तक कि आप जावा संसाधन लीक के बारे में कुछ नहीं जानते जो मैं नहीं करता हूं। – ykaganovich

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^