2009-12-16 8 views
13

रद्द मैं एक लंबे चल रहा काम, जैसे कुछ है:जावा लंबी चलने कार्य थ्रेड बीच में बनाम झंडा

public void myCancellableTask() { 
    while (someCondition) { 
     checkIfCancelRequested(); 
     doSomeWork(); 
    } 
} 

कार्य रद्द किया जा सकता है (एक रद्द करने का अनुरोध किया जाता है और checkIfCancelRequested() झंडा रद्द की जाँच करता है)। आम तौर पर जब मैं इस तरह से रद्द करने योग्य लूप लिखता हूं, तो मैं यह इंगित करने के लिए एक ध्वज का उपयोग करता हूं कि रद्द करने का अनुरोध किया गया है। लेकिन, मुझे पता है कि मैं Thread.interrupt का भी उपयोग कर सकता हूं और जांच सकता हूं कि थ्रेड बाधित हो गया है या नहीं। मुझे यकीन नहीं है कि कौन सा पसंदीदा दृष्टिकोण होगा और क्यों, विचार?

धन्यवाद,

जेफ

उत्तर

6

इंटरप्ट निर्दिष्ट इंतजार शर्तों की सूची से बाहर धागा विस्फोट होगा। आपका खुद का रद्द ध्वज नहीं होगा। यदि आप आईओ और घटनाओं पर इंतजार करना चाहते हैं, तो बाधा का उपयोग करें। अन्यथा अपने आप का उपयोग करें।

0

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

1

यह doSomeWork() कार्यान्वयन पर निर्भर करता है। क्या यह शुद्ध गणना है या यह (किसी भी बिंदु पर) ब्लॉकिंग एपीआई (जैसे आईओ) कॉल शामिल है? प्रति bmargulies के उत्तर, जेडीके में कई अवरुद्ध एपीआई इंटरप्टिव हैं और स्टैक को बाधित अपवाद को प्रसारित करेंगे।

तो, अगर काम संभावित गतिविधियों को अवरुद्ध जरूरत पर जोर देता है, तो आप ध्यान में बीच में आता है लेने के लिए भले ही आप एक ध्वज का उपयोग कर प्रक्रिया को नियंत्रित करने का फैसला need'll, और उचित रूप से पकड़ने और संभाल चाहिए/बीच में आता है का प्रचार।

इसके अलावा, अगर ध्वज पर भरोसा करते हैं, तो सुनिश्चित करें कि आपका ध्वज volatile अर्थशास्त्र के साथ घोषित किया गया है।

20

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

public void doSomeWork() { 
    try { 
     api.callAndWaitAnswer() ; 
    } 
    catch (InterruptedException e) { throw new AssertionError(); } 
} 

अब आप एक AssertionError (या जो कुछ भी पुस्तकालय आप फेंक सकती है प्रयोग कर रहे हैं) को संभालने के लिए है:

अपने उदाहरण में, doSomeWork एक 3 पक्ष के जार में था और लगता है कि लगता है। मैंने अनुभवी डेवलपर्स को इंटरप्ट प्राप्त करने पर बकवास के सभी प्रकार फेंक दिया है! दूसरी ओर, शायद विधि इस तरह देखा:

public void doSomeWork() { 
    while (true) { 
     try { 
      return api.callAndWaitAnswer() ; 
     } 
     catch (InterruptedException e) { /* retry! */ } 
    } 
} 

व्यवधान की यह "अनुचित हैंडलिंग" अनिश्चित काल के पाश करने के लिए अपने कार्यक्रम का कारण बनता है। दोबारा, हास्यास्पद के रूप में इसे खारिज मत करो; वहाँ बहुत टूटे हुए इंटरप्ट हैंडलिंग तंत्र हैं।

कम से कम अपने ध्वज का उपयोग किसी तीसरे पक्ष के पुस्तकालयों के लिए पूरी तरह से अदृश्य हो जाएगा।

+1

अच्छी चीजें यहाँ। बाधा के निगलने या केवल अवरोध झंडा को रीसेट किए बिना लॉगिंग और जारी रखने के लिए यह बहुत आम है। मुझे लगता है कि लोग निराश हो जाते हैं कि यह एक चेक अपवाद है जिसे वे नहीं जानते कि क्या करना है, इसलिए वे कुछ भी नहीं करते हैं। –

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