यदि मैं नहीं हूँ तो जावा थ्रेड इंटरप्ट () विधि को कौन कह रहा है?


87

मैंने अभ्यास में जावा कंसीडर को फिर से पढ़ा और पढ़ा है, मैंने इस विषय पर यहां कई सूत्र पढ़े हैं, मैंने आईबीएम लेख पढ़ा है जिसमें व्यवधान डाला गया है और फिर भी कुछ ऐसा है जिसे मैं आसानी से समझ नहीं पा रहा हूं जिसे मैं तोड़ सकता हूं नीचे दो प्रश्नों में:

  1. अगर मैं कभी भी अन्य थ्रेड्स को अपने आप में बाधित नहीं कर रहा हूं, तो एक इंटरप्टेड अपवाद को ट्रिगर क्या कर सकता है ?

  2. अगर मैं कभी भी अन्य थ्रेड्स को स्वयं बाधित नहीं कर रहा हूं, तो () (क्योंकि मैं अपने काम के धागे को रद्द करने के लिए अन्य साधनों का उपयोग कर रहा हूं, जैसे जहर की गोलियाँ और जबकि (रद्द) स्टाइल लूप [जैसा कि दोनों ने जेसीआईपी में समझाया है)), क्या एक InterruptedException तो मतलब है? एक को पकड़ने पर मुझे क्या करना चाहिए? शटडाउन माय ऐप?

जवाबों:


50

थ्रेड इंटरप्ट मैकेनिज्म एक (सहयोग करने वाला) धागा प्राप्त करने का पसंदीदा तरीका है जो कि यह क्या कर रहा है इसे रोकने के अनुरोध का जवाब देता है। कोई भी धागा (मुझे लगता है कि धागा सहित) interrupt()एक थ्रेड पर कॉल कर सकता है ।

व्यवहार में, interrupt()किसी तरह के ढांचे या प्रबंधक को कुछ कार्यकर्ता थ्रेड को बताने के लिए सामान्य उपयोग के मामलों को रोकने के लिए कि वे क्या कर रहे हैं। यदि श्रमिक धागा "इंटरप्ट अवेयर" है, तो यह नोटिस करेगा कि यह एक अपवाद के माध्यम से बाधित किया गया है, या समय-समय पर अपने बाधित ध्वज की जांच कर रहा है। यह देखते हुए कि यह बाधित हो गया है, एक अच्छी तरह से व्यवहार किए गए धागे को छोड़ देना चाहिए जो यह कर रहा है और खुद को समाप्त कर रहा है।

उपरोक्त उपयोग-मामले को मानते हुए, यदि आपका कोड जावा फ्रेमवर्क में या कुछ वर्कर थ्रेड से चलाया जाता है, तो आपके कोड के बाधित होने की संभावना है। और जब यह बाधित होता है, तो आपके कोड को यह छोड़ देना चाहिए कि यह क्या कर रहा है और सबसे उपयुक्त साधनों द्वारा खुद को समाप्त करने का कारण बनता है। आपके कोड को कैसे बुलाया गया था, इस पर निर्भर करते हुए, यह वापसी या कुछ उपयुक्त अपवाद को फेंककर किया जा सकता है। लेकिन यह शायद फोन नहीं करना चाहिए System.exit()। (आपके एप्लिकेशन को जरूरी नहीं पता है कि यह क्यों बाधित हुआ था, और यह निश्चित रूप से नहीं जानता है कि क्या अन्य धागे हैं जिन्हें रूपरेखा द्वारा बाधित करने की आवश्यकता है।)

दूसरी ओर, यदि आपका कोड कुछ ढांचे के नियंत्रण में चलाने के लिए डिज़ाइन नहीं किया गया है, तो आप तर्क दे सकते हैं कि InterruptedExceptionयह एक अप्रत्याशित अपवाद है; यानी एक बग। उस मामले में, आपको अपवाद का इलाज करना चाहिए क्योंकि आप अन्य कीड़े होंगे; उदाहरण के लिए इसे अनियंत्रित अपवाद में लपेटें, और इसे उसी बिंदु पर लॉग इन करें, जब आप अन्य अनियंत्रित अपवादों से निपटते हैं। (वैकल्पिक रूप से, आपका एप्लिकेशन केवल व्यवधान को अनदेखा कर सकता है और वही कर सकता है जो वह कर रहा था।)


1) यदि मैं कभी भी अन्य थ्रेड्स को अपने आप में बाधित नहीं कर रहा हूं, तो एक इंटरप्टेड अपवाद को कैसे ट्रिगर किया जा सकता है?

एक उदाहरण यदि आपका है Runnableवस्तुओं का उपयोग कर क्रियान्वित कर रहे हैं ExecutorServiceऔर shutdownNow()सेवा पर कहा जाता है। और सिद्धांत रूप में, कोई भी 3-पार्टी थ्रेड पूल या थ्रेड मैनेजमेंट फ्रेमवर्क वैध रूप से ऐसा कुछ कर सकता है।

2) अगर मैं कभी भी अन्य धागों को बीच में रोक कर खुद को बाधित () नहीं कर रहा हूँ ... InterruptedExceptionतो इसका क्या मतलब है? एक को पकड़ने पर मुझे क्या करना चाहिए? शटडाउन माय ऐप?

आपको यह जानने के लिए कोडबेस का विश्लेषण करने की आवश्यकता है कि interrupt()कॉल क्या और क्यों कर रहा है। एक बार जब आपको पता चल गया कि आप काम कर सकते हैं, तो आपके << ऐप का हिस्सा क्या करना है।

जब तक आप यह नहीं जानते कि क्यों InterruptedExceptionफेंका जा रहा है, मैं इसे एक कठिन त्रुटि मानने की सलाह दूंगा; उदाहरण के लिए, लॉग फ़ाइल में एक स्टैकट्रेस प्रिंट करें और ऐप को बंद करें। (जाहिर है, यह हमेशा सही जवाब नहीं है ... लेकिन मुद्दा यह है कि यह "बग" है, और इसे डेवलपर / अनुरक्षक के ध्यान में लाया जाना चाहिए।)

3) मुझे कैसे पता चलेगा कि कौन / क्या कॉल कर रहा है interrupt()?

इसका कोई अच्छा जवाब नहीं है। सबसे अच्छा मैं सुझाव दे सकता हूं Thread.interrupt()कि कॉल स्टैक पर एक ब्रेकपॉइंट सेट करें और देखें।


12

यदि आप अपने कोड को अन्य पुस्तकालयों के साथ एकीकृत करने का निर्णय लेते हैं, तो वे interrupt()आपके कोड पर कॉल कर सकते हैं । उदाहरण के लिए, यदि आप भविष्य में अपने कोड को ExecutorService के भीतर निष्पादित करने का निर्णय लेते हैं , तो यह एक शटडाउन के माध्यम से मजबूर कर सकता है interrupt()

इसे संक्षेप में कहने के लिए, मैं न केवल यह सोचूंगा कि आपका कोड अभी कहां चल रहा है , लेकिन भविष्य में यह किस संदर्भ में चल सकता है। उदाहरण के लिए आप इसे एक पुस्तकालय में रखने जा रहे हैं? एक बक्सा ? अन्य लोग इसका उपयोग कैसे करेंगे? क्या आप इसे पुन: उपयोग करने जा रहे हैं?


मैंने सोचा था कि केवल शट डाउननॉउन इंटरप्ट () विधि को कॉल करता है। क्या यह शटडाउन के लिए भी सही है?
हरिंदर

9

जैसा कि दूसरों ने बताया है, एक थ्रेड को बाधित करना (वास्तव में, एक अवरुद्ध कॉल को बाधित करना) आमतौर पर सफाई से बाहर निकलने या किसी चल रही गतिविधि को रद्द करने के उद्देश्यों के लिए उपयोग किया जाता है।

हालांकि, आपको InterruptedExceptionअकेले "कमांड छोड़ना" के रूप में व्यवहार नहीं करना चाहिए । इसके बजाय, आपको थ्रेड की चल रही स्थिति को नियंत्रित करने के साधन के रूप में दखल के बारे में सोचना चाहिए, उसी तरह से जैसा कि Object.notify()करता है। उसी तरह जिसे आप कॉल से जागने के बाद वर्तमान स्थिति की जांच करेंगे Object.wait()(आप यह नहीं मानते हैं कि वेकअप का अर्थ है कि आपकी प्रतीक्षा की स्थिति संतुष्ट है), एक रुकावट के साथ नग्न होने के बाद आपको जांच करनी चाहिए कि आपको क्यों बाधित किया गया था । आमतौर पर ऐसा करने का एक तरीका है। उदाहरण के लिए, java.util.concurrent.FutureTaskएक isCancelled()विधि है।

कोड नमूना:

public void run() {
    ....
    try {
        .... // Calls that may block.
    } catch (InterruptedException e) {
        if (!running) {  // Add preferred synchronization here.
            return; // Explicit flag says we should stop running.
        }
        // We were interrupted, but the flag says we're still running.
        // It would be wrong to always exit here. The interrupt 'nudge'
        // could mean something completely different. For example, it
        // could be that the thread was blocking on a read from a particular
        // file, and now we should read from a different file.
        // Interrupt != quit (not necessarily).
    }
    ....
}
public void stop() {
    running = false; // Add preferred synchronization here.
    myThread.interrupt();
}

3

प्रश्न के साथ समस्या "मैं" है। "मैं" आमतौर पर एक वर्ग के एक उदाहरण को संदर्भित करता है। मेरा मतलब है कि, निम्न-स्तरीय कोड (वर्ग) के किसी विशेष टुकड़े को पूरी प्रणाली के कार्यान्वयन पर भरोसा नहीं करना चाहिए। यह कहने के बाद कि आपके पास कुछ "वास्तुशिल्प" निर्णय हैं (जैसे कि किस प्लेटफॉर्म पर चलना है)।

JRE से आने वाले संभावित अनपेक्षित व्यवधानों java.util.concurrentको एप्लेट्स को बंद और बंद करने के कार्य रद्द कर दिए गए हैं ।

थ्रेड इंटरप्ट की हैंडलिंग आमतौर पर गलत तरीके से लिखी जाती है। इसलिए, मैं जहां संभव हो वहां व्यवधान पैदा करने से बचने के लिए वास्तु निर्णय का सुझाव देता हूं। हालांकि, कोड हैंडलिंग इंटरप्ट्स हमेशा सही ढंग से लिखे जाने चाहिए। अब प्लेटफ़ॉर्म से बाहर व्यवधान नहीं ला सकते।


हाय टॉम, मुझे आपका नाम क्लैप से याद है;) ठीक है, ठीक है: मुझे कभी भी व्यवधान नहीं डालना था () खुद ... जब तक मैं एक InterruptedException को पकड़ रहा हूं और बाधित स्थिति पर फिर से दावा करने की जरूरत है, लेकिन यह अभी भी 100% नहीं है मेरे लिए स्पष्ट है। मैं यहां नया हूं और अपवोट और उत्तर / टिप्पणियों (दोनों सही और गलत दोनों) की संख्या से हैरान हूं: जाहिर है कि यह एक ऐसा विषय है जो तुच्छ नहीं है या कम से कम, आमतौर पर अच्छी तरह से समझाया नहीं गया है। उस ने कहा कि सभी पोस्ट के लिए धन्यवाद, जो शुरू होने जा रहा है उसकी एक स्पष्ट तस्वीर मुझे मिल रही है :)
SyntaxT3rr0r

3

आप अपनी स्वयं की थ्रेड क्लास (फैली हुई java.lang.Thread) और ओवरराइडिंग interrupt()विधि बनाकर इसे सीख सकते हैं , जिसमें आप स्टैकट्रेस को रिकॉर्ड करते हैं, कहते हैं, एक स्ट्रिंग फ़ील्ड, और फिर सुपर.इन्ट्रप्ट () में स्थानांतरित करें।

public class MyThread extends Thread {

    public volatile String interruptStacktrace; // Temporary field for debugging purpose.

    @Override
    public void interrupt() {
        interruptStacktrace = dumpStack(); // You implement it somehow...

        super.interrupt();
    }
}

1

जैसा कि पहले ही उल्लेख किया गया है, एक अन्य पुस्तकालय आपके थ्रेड्स को बाधित कर सकता है। यहां तक ​​कि अगर लाइब्रेरी में आपके कोड से थ्रेड्स तक स्पष्ट पहुंच नहीं है, फिर भी वे उन थ्रेड्स की सूची प्राप्त कर सकते हैं जो चल रहे हैं और उन्हें उस तरीके से बाधित कर रहे हैं जो निम्न विधि के साथ है


1

मुझे लगता है कि मैं समझता हूं कि आप रुकावट के बारे में थोड़ा भ्रमित क्यों हैं। कृपया मेरे उत्तरों पर विचार करें:

अगर मैं कभी भी अन्य थ्रेड्स को अपने आप में बाधित नहीं कर रहा हूं, तो एक इंटरप्टेड अपवाद को ट्रिगर क्या कर सकता है ?

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

कई तरीके हैं जिनके कारण अभी भी रुकावटें हो सकती हैं, समयबाह्य हो सकती हैं, जेवीएम इंटरप्ट आदि।

अगर मैं कभी भी अन्य थ्रेड्स को स्वयं बाधित नहीं कर रहा हूं, तो () (क्योंकि मैं अपने काम के धागे को रद्द करने के लिए अन्य साधनों का उपयोग कर रहा हूं, जैसे जहर की गोलियाँ और जबकि (रद्द) स्टाइल लूप [जैसा कि दोनों ने जेसीआईपी में समझाया है)), क्या एक InterruptedException तो मतलब है? एक को पकड़ने पर मुझे क्या करना चाहिए? शटडाउन माय ऐप?

आपको यहां बहुत सावधान रहने की आवश्यकता है; यदि आप थ्रेड को बाधित करते हैं जो InterruptedException (IE) फेंकता है, तो आप जानते हैं कि इसे पकड़ने पर क्या करना है, कहते हैं कि आप अपने ऐप / सेवा को बंद कर सकते हैं या आप इस मारे गए धागे को एक नए के साथ बदल सकते हैं! हालाँकि, यदि आपके पास थ्रेड नहीं है, तो IE को पकड़ने पर या तो कॉल स्टैक को उच्चतर रूप से रीहैरो कर देता है या कुछ करने के बाद (लॉगिंग हो सकती है), बाधित स्थिति को रीसेट कर देता है ताकि कोड जो इस थ्रेड का मालिक हो, जब नियंत्रण उस तक पहुंच जाए, तो सीखें कि थ्रेड बाधित हो गया था और इसलिए कार्रवाई करें क्योंकि यह केवल रुकावट नीति को जानता है।

उम्मीद है कि इससे मदद मिली।


0

का InterruptedExceptionकहना है कि एक दिनचर्या बाधित हो सकती है, लेकिन जरूरी नहीं कि यह होगी।

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

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