2011-09-26 16 views
8

मैं प्रैक्टिस में जावा कंसुरेंसी पुस्तक पढ़ रहा हूं। java.util.concurrent.Semaphore के बारे में एक अनुभाग में, नीचे दी गई पंक्तियां पुस्तक में मौजूद हैं। यह "आभासी परमिट 'की इसके कार्यान्वयन के बारे में एक टिप्पणी वस्तुओंसेमेफोर किस प्रकार और क्यों शुरू कर सकता है उससे अधिक परमिट देता है?

कार्यान्वयन कोई वास्तविक परमिट वस्तुओं है, और Semaphore धागे के साथ समाप्त परमिट, तो एक परमिट एक थ्रेड में अधिग्रहण से जारी कर सकते हैं संबद्ध नहीं करता जा एक और धागा आप बनाने जैसा एक परमिट और release लेने के रूप में acquire के बारे में सोच सकते हैं; एक Semaphore परमिट इसके साथ बनाया गया था की संख्या तक सीमित नहीं है।

क्या कोई इसे समझा सकता है? मुझे यह समझने में परेशानी हो रही है। यदि हम निश्चित आकार का पूल बनाते हैं, तो हम "परमिट" की एक निश्चित संख्या बनाते हैं। उपर्युक्त कथन से, ऐसा लगता है कि "परमिट" बढ़ते रह सकते हैं। इस तरह से डिजाइन क्यों किया गया है?

+0

सिर्फ ऑर्नेट वाक्यांश की तरह दिखता है – gstackoverflow

उत्तर

8
परमिट वस्तुओं "बाहर सौंपने" के बजाय

, कार्यान्वयन सिर्फ एक काउंटर है। जब एक नया परमिट "बनाया गया" काउंटर बढ़ जाता है, जब परमिट "लौटाया जाता है" काउंटर कम हो जाता है।

यह वास्तविक वस्तुओं हर समय बनाने की तुलना में बेहतर प्रदर्शन के लिए बनाता है।

ट्रेडऑफ यह है कि सेमफोर स्वयं कुछ प्रकार की प्रोग्रामिंग त्रुटियों (जैसे अनधिकृत परमिट कैश-इन्स, या सेमफोर लीक) का पता नहीं लगा सकता है। कोडर के रूप में, आपको अपने नियमों का पालन करना सुनिश्चित करना होगा।

+0

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

+0

@Dasmowenator: मुझे लगता है कि आप परमाणु इंटेगर के शीर्ष पर अपना खुद का रोल कर सकते हैं। लेकिन यह एक अच्छा दृष्टिकोण की तरह नहीं लगता है। आपको वास्तव में यह सुनिश्चित करना चाहिए कि आपका लॉकिंग कोड तार्किक रूप से सही है। अगर आपको नो-ऑप रिलीज करने की आवश्यकता मिलती है, तो शायद इसका मतलब है कि कोई भी उनके पास अधिक ताले जारी कर रहा था। और यह उन चीजों को तोड़ देगा जो कुछ सेमफोर कॉलों को अनदेखा करके तय नहीं किए जा सकते हैं। – Thilo

+0

आप लॉकिंग के पारंपरिक "सिंक्रनाइज़" तरीके का भी उपयोग कर सकते हैं। कम लचीला, लेकिन सुरक्षित (कोई रिसाव नहीं, फिर से प्रवेश की देखभाल करता है)। – Thilo

5

क्या कोई इसे समझा सकता है? उपर्युक्त कथन से, ऐसा लगता है कि "परमिट" बढ़ते रह सकते हैं।

एक सेमफोर परमिट का एक काउंटर है। अधिग्रहण कमी की तरह है जो शून्य से नीचे जाने की बजाय प्रतीक्षा करता है। इसकी कोई ऊपरी सीमा नहीं है।

यह इस तरह से डिज़ाइन क्यों किया गया है?

क्योंकि ऐसा करना आसान है।

+0

कोई ऊपरी सीमा नहीं है, ऊपरी सीमा परमिट की संख्या नहीं होगी? – Scorpion

+0

ऊपरी सीमा कई बार रिलीज़ होने की संख्या से कम होने की संख्या कम हो जाती है। आप किसी भी समय रिलीज कॉल कर सकते हैं। कुछ कार्यान्वयन में Integer.MAX_VALUE की ऊपरी सीमा है। –

+0

तो अधिकतम 1 के साथ एक ठोस सेमफोर बनाने के बारे में कैसे जाता है - इस पर ध्यान दिए बिना कि कितनी बार रिलीज कहा जाता है? – slott

2

मुझे लगता है कि यह बार के रूप में कई बार हम "अतिरिक्त" प्लस जारी किया है और परमिट इसके साथ बनाया है कि हम क्या सेमाफोर की आवश्यकता हो सकती है।

जैसे:

Semaphore s = new Semaphore(1); // one permit when initialize 

s.acquire(); 
s.release(); 

s.release(); // "extra" release. 

इस समय, इस सेमाफोर की अनुमति देता है एक परमिट मूल रूप से और एक "अतिरिक्त" परमिट

-1

शायद अंतिम पंक्ति "एक सेमाफोर परमिट की संख्या तक सीमित नहीं है यह "भ्रम का स्रोत है" के साथ बनाया गया था।

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

इसका अर्थ यह है कि उद्धृत रेखा (जेसीआईपी से) यह है: सबसे पहले, सेमेफोर कैसे काम करता है, परमिट जारी करने और प्राप्त करने के विवरण तक ही सीमित नहीं है - यह इस तथ्य में प्रकट होता है कि कोई भी धागा सेमफोर तक पहुंचने पर परमिट जारी किया जा सकता है (भले ही इस धागे के पास पहली जगह परमिट नहीं है)

दूसरा, आप reducePermits(int) विधि को कॉल करके - सेमफोर के अधिकतम परमिट को गतिशील रूप से कम कर सकते हैं।

3

पहली पोस्ट में उल्लेख किया

हर कॉल .release करने के लिए "सेमाफोर परमिट यह साथ बनाया गया था की संख्या तक सीमित नहीं है"() API एक के बाद परमिट गिनती में वृद्धि होगी। तो सेमफोरस में एक निश्चित परमिट आकार नहीं है

+0

क्या आप .release() को तब काम कर सकते हैं? तो, अगर मैं 0 के साथ एक सेमफोर ऑब्जेक्ट बनाता हूं तो कोई थ्रेड इससे परमिट प्राप्त नहीं कर सकता है? लेकिन अगर मैं अगली पंक्ति में पहले और फिर .acquire() पर .release() को कॉल करता हूं, तो यह थ्रेड को परमिट प्राप्त करने की अनुमति देगा? –

1

हम में से कुछ के लिए यह आश्चर्यजनक है।

आप आसानी से एक बाध्य सेमफोर उपclass कर सकते हैं।

/** 
* Terrible performance bounded semaphore. 
**/ 
public class BoundedSemaphore extends Semaphore { 
    private static final long serialVersionUID = -570124236163243243L; 
    final int bound; 
    public BoundedSemaphore(int permits) { 
     super(permits); 
     bound=permits; 
    } 

    @Override 
    synchronized public void acquire() throws InterruptedException { 
     super.acquire(); 
    } 

    @Override 
    synchronized public boolean tryAcquire() { 
     return super.tryAcquire(); 
    } 

    @Override 
    synchronized public void release() { 
     if(availablePermits()<bound){ 
      super.release(); 
     } 
    } 
    @Override 
    synchronized public void acquire(int count) throws InterruptedException { 
     super.acquire(count); 
    } 

    @Override 
    synchronized public boolean tryAcquire(int count) { 
     return super.tryAcquire(count); 
    } 

    @Override 
    synchronized public void release(int count) { 
     if(availablePermits()<bound){ 
      super.release(bound-availablePermits()); 
     } 
    } 
} 
संबंधित मुद्दे