2012-08-28 23 views
9

एक प्रतीत होता है सीधा समस्या: मेरे पास java.util.concurrent.Semaphore है, और मैं acquire() का उपयोग कर परमिट प्राप्त करना चाहता हूं।क्या सेमफोर.एक्वायर() फेंकने के कारण इंटरप्टेड एक्सेप्शन फेंक सकता है?

acquire() विधि InterruptedException फेंक अगर धागा बाधित है निर्दिष्ट किया जाता है:

वर्तमान धागा हैं:

  • अपने बाधित स्थिति इस विधि में प्रवेश पर स्थापित किया है; या
  • जबकि एक परमिट के लिए इंतजार बाधित है,

तो InterruptedException फेंक दिया जाता है और वर्तमान थ्रेड बाधित स्थिति को मंजूरी दे दी है।

हालांकि, तरीकों फेंक सकता है कि InterruptedException उन्हें एक पाश में कॉल करने के लिए है, क्योंकि सूत्र नकली wakeups कि बाधित किया जा रहा के रूप में ही देखने के लिए विषय हो सकता है के साथ सामान्य पैटर्न। उदाहरण के लिए, documentation for Object.wait(long) कहता है:

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

तो सवाल यह है कि Semaphore.acquire() उसी तरह के नकली wakeupup के अधीन है? तार्किक उत्तर "नहीं" होगा, लेकिन मुझे इसके लिए कोई सबूत नहीं मिल रहा है, और वास्तव में सबूत दूसरी दिशा में इंगित होते हैं।

source for Semaphore को देखते हुए, ऐसा लगता है कि यह एक AbstractQueuedSynchronizer करने के लिए वास्तविक अधिग्रहण, जो LockSupport.park() को its source प्रतिनिधियों के अनुसार प्रतिनिधियों।

documentation for LockSupport.park() स्पष्ट रूप से नकली Wakeup का उल्लेख है, लेकिन AbstractQueuedSynchronizer.doAcquireInterruptably() के कार्यान्वयन प्रकट होता है बस Thread.interrupted() जाँच करने के लिए और फिर InterruptedException फेंक देते हैं।

तो, जब तक मैं कुछ (जो बहुत संभव है) याद कर रहा हूँ, यह है कि Semaphore.acquire()कर सकते हैं फेंक InterruptedException नकली तौर पर दिखाई देता है?

क्या यह सही है? सबसे महत्वपूर्ण बात यह है कि क्या मैं इसके बारे में कुछ भी कर सकता हूं? मैं Semaphore.acquireUninterruptably() का उपयोग कर सकता हूं, लेकिन मैं एक निर्बाध प्रतीक्षा नहीं चाहता हूं, केवल एक जो क्रोधित रूप से बाधित नहीं होता है। क्या कोई विकल्प है?

+2

यह "नकली जागरूकता" नहीं है "नकली बाधा": "एक थ्रेड भी अधिसूचित, बाधित, या समय-समय पर एक तथाकथित जासूसी जागने के बिना जाग सकता है।" एक नकली जागरूकता के दौरान कोई हस्तक्षेप नहीं किया गया है। –

+0

@SkipHead: तो धागा उठता है, लेकिन 'बाधित' ध्वज सेट नहीं है? यह समझ में आता है - क्या आप इसे उत्तर के रूप में पोस्ट कर सकते हैं? –

उत्तर

7

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

2

मुझे लगता है कि अगर आप Semaphore.acquire() एपीआई के बारे में सोचते हैं, तो आपको पता चलेगा कि इसके लिए एक नकली जागरूकता है, क्योंकि मुख्य रूप से कॉलर के पास "सामान्य" के लिए "नकली" अंतर करने का कोई तरीका नहीं होगा, और इसलिए विधि बेकार होगी।

+0

सहमत हुए, और इसलिए मैंने सवाल पूछा। मैंने जितना अधिक माना, और बस मेरी धारणा को सत्यापित करने के लिए कोड की जांच करने के लिए गया, लेकिन मैं परेशान था क्योंकि मुझे लगता है कि एक नकली विफलता हो सकती है, इसलिए मैंने पुष्टि करने के लिए यहां पूछा। –