जावा में Ctrl + C पकड़ना


80

क्या java कमांड-लाइन एप्लिकेशन में Ctrl+ Cसिग्नल पकड़ना संभव है ? मैं कार्यक्रम समाप्त करने से पहले कुछ संसाधनों को साफ करना चाहता हूं।

जवाबों:


89

आप VM को शटडाउन हुक संलग्न कर सकते हैं जो कि जब भी वीएम शट डाउन हो जाता है:

दो प्रकार की घटनाओं के जवाब में जावा वर्चुअल मशीन बंद हो जाती है:

  • प्रोग्राम सामान्य रूप से बाहर निकलता है, जब अंतिम गैर-डेमन थ्रेड बाहर निकलता है या जब निकास (समकक्ष, System.exit) विधि लागू होती है, या

  • वर्चुअल मशीन उपयोगकर्ता के अवरोधन, जैसे कि टाइपिंग Ctrl+ C, या सिस्टम-वाइड इवेंट, जैसे उपयोगकर्ता लॉगऑफ़ या सिस्टम शटडाउन के जवाब में समाप्त हो जाती है ।

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

इसके अलावा, जैसा कि टिप्पणी करने वाले जेसपर बताते हैं, शटडाउन हुक को वीएम के सामान्य शटडाउन पर चलने की गारंटी है लेकिन अगर वीएम प्रक्रिया को जबरन समाप्त किया जाता है तो वे नहीं करते हैं। यह हो सकता है यदि देशी कोड खराब हो जाए या यदि आप जबरन प्रक्रिया को मार दें ( kill -9,taskkill /f ) ।

लेकिन उन परिदृश्यों में सभी दांव वैसे भी बंद हैं, इसलिए मैं इस पर बहुत अधिक विचार नहीं करूंगा।


1
खबरदार कि शटडाउन हुक को सभी परिस्थितियों में चलाने की गारंटी नहीं है; ऐसी स्थितियाँ हो सकती हैं जहाँ वे नहीं चलते हैं, इसलिए अपने कार्यक्रम के सही कामकाज को इस बात पर निर्भर न करें कि आप शटडाउन हुक में क्या करते हैं।
जेसपर

4
वे नहीं चलाए जाते हैं, जब प्रक्रिया को बलपूर्वक ( TerminateProcess()या SIGKILL) समाप्त कर दिया जाता है, लेकिन यह सामान्य ऑपरेशन से बाहर है और चूंकि Ctrl + C पहले से ही शटडाउन हुक द्वारा कवर किया गया है, इसलिए इसका उपयोग करना सुरक्षित है। यदि ओएस वास्तव में आपकी प्रक्रिया को समाप्त कर देता है तो आप बहुत कुछ नहीं कर सकते।
जोय

1
kill -HUPयूनिक्स से "सबसे नरम" मार है, और शटडाउन हुक चलाना चाहिए। डिफ़ॉल्ट के बारे में निश्चित नहीं है kill
livefree75

1
डिफ़ॉल्ट मार मेरी मशीन (Redhat 7.3) पर शटडाउन हुक को चलाने का कारण बनता है। किल -9 नहीं है।
माइककूल

2
शटडाउन हुक को किसी विशेष क्रम में चलाने की गारंटी नहीं है, इसलिए यदि आपका शटडाउन हुक अन्य शटडाउन हुक पर निर्भर करता है जो अभी तक नहीं चलाया जा रहा है (या इसके विपरीत), तो आप समस्याओं में भाग सकते हैं।
ल्यूक हचिसन

28

बस त्वरित कंसोल परीक्षण प्रयोजनों के लिए ...

Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            try {
                Thread.sleep(200);
                System.out.println("Shutting down ...");
                //some cleaning up code...

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                e.printStackTrace();
            }
        }
    });

0

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

Signal.handle(new Signal("INT"),  // SIGINT
    signal -> System.out.println("Interrupted by Ctrl+C"));

Signalवर्तमान में है sun.misc.Signal, जिसका अर्थ है कि यह पदावनत किया जाएगा - लेकिन जिसे इसके साथ प्रतिस्थापित किया जा रहा है उसे वर्तमान में नाम दिया गया है jdk.internal.misc.Signal, इसलिए जब तक कि जावा टीम यह पता नहीं लगाती कि गैर-आंतरिक तरीके से सिग्नल हैंडलर को सार्वजनिक रूप से कैसे उजागर किया जाए, तो सावधान रहें कि यह कॉल दूर हो सकती है। अभी के लिए (JDK 11 के अनुसार), sun.misc.Signalअभी भी मौजूद है।

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