2012-09-01 13 views
6

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

ये सभी कनेक्शन थ्रेड एक समवर्ती हैशप में संग्रहीत हैं।

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

मैं विशिष्ट कनेक्शन थ्रेड (हैशपैप से) पुनर्प्राप्त करता हूं और उस पर इंटरप्ट() विधि को कॉल करता हूं।

तो, यहां प्रश्न है, कनेक्शन थ्रेड के भीतर, मैं इंटरप्टेड एक्सेप्शन को कैसे पकड़ूं? (जब मैं बाहरी रीस्टफुल कमांड द्वारा कनेक्शन थ्रेड को रोकता हूं तो मैं कुछ करना चाहता हूं।)

+0

ठीक है, AFAIK, जब थ्रेड इंटरप्टेडएक्स फेंकता है। यह उस धागे तक फैल जाएगा जिसने अपवाद फेंकने का अपवाद शुरू किया था। यह उस पैरेंट थ्रेड पर है जिसे आप आईई पकड़ सकते हैं। –

+0

मैंने कनेक्शन थ्रेड शुरू करने वाले कोड को घेरने के लिए अभी एक प्रयोग किया है, और संकलक चेतावनी देता है कि इंटरप्टेड एक्सेप्शन फेंक नहीं दिया गया है। – ikevin8me

+0

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

उत्तर

6

तो, यहां सवाल है, कनेक्शन थ्रेड के भीतर, मैं इंटरप्टेड एक्सेप्शन कैसे पकड़ूं?

आप नहीं कर सकते। चूंकि आपका धागा पढ़ने के लिए I/O ऑपरेशन पर अवरुद्ध है, तो यह interrupted नहीं हो सकता है। ऐसा इसलिए है क्योंकि interrupt यह इंगित करने के लिए एक ध्वज सेट करता है कि धागा बाधित हो गया है। लेकिन अगर आपका धागा I/O के लिए अवरुद्ध कर दिया गया है तो यह ध्वज नहीं देखेगा।
इसके लिए उचित तरीका अंतर्निहित सॉकेट को बंद करना है (कि धागा अवरुद्ध है), फिर अपवाद पकड़ें और इसे प्रसारित करें।यह एक धागा मैं/हे पर अवरुद्ध बाधित करने के लिए संभव है

@Override 
public void interrupt(){ 
    try{ 
     socket.close(); 
    } 
    finally{ 
    super.interrupt(); 
    } 
} 

इस तरह:
तो धागे extend Thread अपने कनेक्शन निम्न कार्य के बाद से।

अपने run विधि में

तब कार्य करें:

@Override 
public void run(){ 

    while(!Thread.currentThread().isInterrupted()){  
     //Do your work 

    } 
}  

तो अपने मामले में catch एक InterruptedException की कोशिश न करें। आप I/O पर अवरुद्ध थ्रेड को बाधित नहीं कर सकते हैं। बस जांचें कि क्या आपका धागा बाधित हो गया है और स्ट्रीम को बंद करके बाधा को सुविधाजनक बनाता है।

2

समस्या को अवरुद्ध करने में समस्या है।

Hoverer, इस कोड की कोशिश, शायद यह तुम्हारी मदद करेगा: अगर वहाँ उदाहरण के लिए सॉकेट पर उपलब्ध buytes है, अगर वहाँ इसे पढ़ने से कर रहे हैं

try{ 
yourObject.read(); 
}catch(InterruptedException ie){ 
// interrupted by other thread 
} 
catch(Exception ex){ 
// io or some other exception happent 
} 

अपने पढ़ने विधि, की जाँच करनी चाहिए, othervise प्ले करने के लिए जाना मोड। शुद्ध सॉकेट पढ़ने (जो भी पढ़ा है) पर जागने (इंटरप्टेड एक्सेप्शन) उपलब्ध होने से सोते समय इसे अवरुद्ध कर दिया जाएगा। कुछ एपीआई में अधिकतम प्रतीक्षा करने का मूल्य होता है, उदाहरण के लिए 5 सेकंड 60 सेकेंड, यदि इससे कुछ भी नहीं पढ़ा जाता है तो अगला कोड निष्पादित किया जाएगा।

class MyReadingObject 
{ 
    public read() throws InterruptedException{ 
     while(shouldIread){ 
     if(socket.available() > 0){ 
      byte[] buff = new byte[socket.avaialble()] 
      socket.read(buff); 
      return; 
     } 
     else{ 
      Thread.currentThread.sleep(whateverMilliseconds); 
     } 
    } 
    } 
} 

ऐसा ही कुछ है, लेकिन त्रुटि हैंडलिंग के साथ और कुछ डिजाइन पैटर्न

+0

मैंने इस तरह कुछ करने की कोशिश की, समस्या यह है कि "yourObject.read()" interruptedException को फेंक नहीं देता है। कंपाइलर एक त्रुटि दिखाएगा कि कोड में कहीं भी उस अपवाद को फेंकता है और संकलन करने से इंकार कर देता है। – ikevin8me

+0

ओह, लेकिन आप इसे जोड़ सकते हैं: –

+0

मुझे लगता है कि मैं नीचे आ गया हूं, मुझे पुनर्विचार करना चाहिए कि मैं यहां कितना समय बर्बाद कर दूंगा। सबको शुक्रीया। सहायक हो, शुभकामनाएँ! –

-1

उपयोग करती हैं इसलिए की तरह एक कोशिश पकड़:

try { 
    //code 
} catch (InterruptedException e) { 
    //interrupted 
} 

मुझे लगता है कि चाल करना चाहिए, आप भी रख सकता है बाहर निकलने के लिए एक बूलियन वैरिएबल, इसलिए यदि वे सही हैं, तो वे उस चर को जांचेंगे,

+0

मैं इसे कहां रखूं? रन() विधि में? - संकलक कहेंगे कि कोड इंटरप्टेड एक्सेप्शन फेंक नहीं देता है और संकलित नहीं करेगा। – ikevin8me

2

जब आप कुछ धागे पर Thread.interrupt() पर कॉल करते हैं, तो क्या होता है 'इंटररू उस थ्रेड के लिए पशन 'ध्वज सेट किया गया है। कुछ विधियां इस ध्वज को जांचती हैं (Thread.interrupted() या Thread.isInterrupted()) और InterruptedException फेंक दें, लेकिन आम तौर पर केवल उन्हीं विधियां जो इसे अवरोधित कर सकती हैं। इसलिए कोई गारंटी नहीं है कि InterruptedException कभी भी बाधित थ्रेड में फेंक दिया जाएगा। यदि आप InterruptedException फेंकने वाली किसी भी विधि को कॉल नहीं करते हैं, तो उस अपवाद को पकड़ने में कोई बात नहीं है, क्योंकि इसे बिल्कुल नहीं फेंक दिया जाएगा। हालांकि आप हमेशा Thread.isInterrupted() पर कॉल करके अपने थ्रेड को बाधित कर सकते हैं या नहीं।

+0

बहुत सच है, आपको mycontroller.getReadingThread() को कॉल करने की आवश्यकता है। Interrupt(); –

1

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

यहां एक समाधान अंतर्निहित कनेक्शन ऑब्जेक्ट का खुलासा करना और स्पष्ट रूप से close() पर कॉल करना है, इसे किसी प्रकार का अपवाद फेंकने के लिए मजबूर करना है, जिसे थ्रेडेड कोड में संभाला जा सकता है। कुछ ऐसा:

class MyAction extends Thread implements Disposable { 

    public void doStuff() { 
    try { 
     byte[] data = this.connection.readFully(); 
    } catch (InterruptedException e) { 
    // possibly interrupted by forceful connection close  
    } 

    @Override 
    public void dispose() { 
    this.connection.close(); 
    } 
} 

// Elsewhere in code 
MyAction action = conMap.get("something"); 
action.dispose(); 
संबंधित मुद्दे

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