2012-08-24 32 views
8

जावा java.util.concurrent से। सैमफोर डॉक्स यह मेरे लिए बिल्कुल स्पष्ट नहीं था कि क्या होता है अगर semaphore.acquire() थ्रेड को अवरुद्ध करता है और बाद में एक इंटरप्टेड अपवाद द्वारा बाधित हो जाता है। क्या सैमफोर मूल्य कम हो गया है और क्या सैमफोर को छोड़ने की आवश्यकता है?semaphore.relase() की आवश्यकता है अगर semaphore.acquire() interruptedException हो जाता है?

वर्तमान में मैं इस तरह कोड का उपयोग कर रहा:

try { 
    // use semaphore to limit number of parallel threads 
    semaphore.acquire(); 
    doMyWork(); 
} 
finally { 
    semaphore.release(); 
} 

या मैं नहीं बल्कि रिलीज() नहीं बुलाना चाहिए एक InterruptedException अधिग्रहण के दौरान होता है जब()?

उत्तर

8

कॉल रिलीज() जब इंटरप्टेड एक्सेप्शन अधिग्रहण() के दौरान होता है?

आपको नहीं करना चाहिए। यदि .acquire() बाधित है, तो सेमफोर अधिग्रहित नहीं किया गया है, इसलिए संभवतः इसे जारी नहीं करना चाहिए।

आपका कोड

// use semaphore to limit number of parallel threads 
semaphore.acquire(); 
try { 
    doMyWork(); 
} 
finally { 
    semaphore.release(); 
} 
+0

धन्यवाद, यह बहुत उचित लगता है। जैसा कि आपने सुझाव दिया है, मैं अपना कोड बदल दूंगा। – kasimir

+5

इस के साथ समस्या यह है कि semaphore.acquire() भी interruptedException फेंकता है। – jblack

0

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

sem.acquire(); 
try{ 
    doMyWork(); 
}finally{ 
    sem.release(); 
} 
3

ओपन स्कूल के स्वीकार किए जाते हैं उत्तर आंशिक रूप से सही है, semaphore.acquire को छोड़कर() भी InterruptedException फेंकता है। तो, 100% सही होने के लिए, कोड इस तरह दिखेगा:

try { 
    semaphore.acquire(); 
    try { 
     doMyWork(); 
    } catch (InterruptedException e) { 
     // do something, if you wish 
    } finally { 
     semaphore.release(); 
    } 
} catch (InterruptedException e) { 
    // do something, if you wish 
} 
+0

क्या यह वास्तव में घोंसला पकड़ने की कोशिश करना आवश्यक है? क्या हम केवल एक कोशिश में सेफफोरे को हासिल और रिलीज़ कर सकते हैं? – Joyce

+2

मान लीजिए कि जब आप सेमफोर.एक्वायर() को कॉल इंटरप्टेड एक्सेप्शन फेंकते हैं तो मामले को गहन रूप से संभालना चाहते हैं, नेस्टेड ट्राई-कैच आवश्यक हैं। InterruptedException कॉल के दौरान semaphore.acquire() पर और इसे हासिल करने के बाद दोनों को फेंक दिया जा सकता है। http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html#acquire() – jblack

+0

क्या यह ठीक है अगर मैं 'इंटरप्टेड एक्सेप्शन ई' के बजाय सामान्य 'अपवाद ई' केस का उपयोग करता हूं '? – Joyce