2012-04-29 13 views
17

मेरे पास कक्षा में नीचे दो विधियों read() और write() हैं।जावा विधि सिंक्रनाइज़ेशन और पारस्परिक बहिष्करण पढ़ने/लिखने

class Store 
{ 

    public void write() 
    { 
    // write to store; 
    } 

    public string read() 
    { 
    // read from store; 
    } 
} 

1) Store ऑब्जेक्ट एक सिंगलटन है।

2) मेरे पास Writer कक्षा है जो स्टोर को लिखती है और कई Reader कक्षाएं जो एक ही समय में स्टोर से पढ़ी जाएंगी।

मेरे आवश्यकता है कि जब लेखक की दुकान में लिख रहा है, सभी पाठकों इंतजार करना चाहिए है। यानी, जब नियंत्रण write() में होता है, तो read() पर सभी कॉल अवरुद्ध होनी चाहिए। मुझे यह कैसे हासिल होगा? मैंने को write() विधि में आजमाया है, लेकिन मेरे लिए काम की तरह प्रतीत नहीं होता है।

+0

आप वर्ग वस्तु पर सिंक्रनाइज़ करने के लिए नहीं करना चाहते हैं ('सिंक्रनाइज़ (foo.class)') लेकिन इसके बजाय उदाहरण पर आप पर काम कर रहे हैं। – andersoj

उत्तर

33

इस मामले में सबसे अच्छा विकल्प एक पाठक-लेखक लॉक का उपयोग करना है: ReadWriteLock। यह एक लेखक की अनुमति देता है, लेकिन कई समवर्ती पाठकों, इसलिए यह इस प्रकार के परिदृश्य के लिए सबसे कुशल तंत्र है।

कुछ नमूना कोड:

class Store 
{ 
    private ReadWriteLock rwlock = new ReentrantReadWriteLock(); 

    public void write() 
    { 
     rwlock.writeLock().lock(); 
     try { 
      write to store; 
     } finally { 
      rwlock.writeLock().unlock(); 
     } 
    } 

    public String read() 
    { 
     rwlock.readLock().lock(); 
     try { 
      read from store; 
     } finally { 
      rwlock.readLock().unlock(); 
     } 
    } 
} 
+0

ReadWriteLock एक इंटरफ़ेस है। ;) –

+0

@ पीटर लॉरी: इसके बारे में क्षमा करें। फिक्स्ड। :) – Tudor

+4

@Tudor आप हमेशा अपने _read लपेट चाहिए store_ और एक _try_ ब्लॉक में आपरेशन store_ को _write और अपने 'अनलॉक करने के लिए सुनिश्चित करने के लिए()' एक _finally_ ब्लॉक इसी को रोकने के लिए है कि ताले बंद कर दिया रहते हैं एक अपवाद तब होता है, तो में तरीकों । – matsev

0

java.util.concurrent पैकेज से ReadWriteLock का प्रयोग करें

3

synchronized सरल समाधान है, इसलिए आप की व्याख्या करनी चाहिए आप से क्या मतलब है "के लिए काम करते की तरह प्रतीत नहीं होता मैं "और शायद हमें दिखाता हूं कि आपने इसका इस्तेमाल कैसे किया।

बेहतर समाधान ReentrantReadWriteLock का उपयोग करना है क्योंकि यह पाठकों के समवर्ती उपयोग की अनुमति देता है।

2

एक विधि किसी वस्तु पर सिंक्रनाइज़ किया जाता है, एक धागा इस विधि ब्लॉक सभी अन्य सूत्र है कि एक और ब्लॉक/विधि कि एक ही वस्तु पर सिंक्रनाइज़ है में प्रवेश करने की कोशिश को क्रियान्वित।

तो, यदि आप लेखक धागे को किसी भी पाठक धागे को पढ़ने के लिए मना करना चाहते हैं, तो आपको लिखने और पढ़ने की विधि दोनों को सिंक्रनाइज़ करना होगा। स्टोर क्लास पर सिंक्रनाइज़ करने का कोई कारण नहीं है। स्टोर वस्तु पर सिंक्रनाइज़ किया जा रहा और अधिक प्राकृतिक है:

public synchronized void write() { 
    write to store; 
} 

public synchronized String read() { 
    read from store; 
} 

लेकिन यह (शायद) एक दोष यह है: यह भी दो पाठक धागे की मनाही है एक ही समय में पढ़ने के लिए। यदि आपको वास्तव में ऐसा होने की आवश्यकता है, तो आपको ReadWriteLock का उपयोग करना चाहिए। लेकिन इससे कोड कम हो जाएगा जो कम प्रदर्शन करने वाला और समझने और बनाए रखने में कठिन होगा। अगर मैं मापता हूं कि यह आवश्यक है तो मैं केवल इसका इस्तेमाल करूंगा।

+0

आप क्यों कहेंगे कि 'ReadWriteLock'' सिंक्रनाइज़ 'से कम प्रदर्शनशील है? ऐसा होने के लिए कोई अच्छा तकनीकी कारण नहीं है क्योंकि सेमफोर मैनिपुलेशन को निर्देशित करने के लिए दोनों विधियों को उच्च स्तर का इंटरफ़ेस होना चाहिए। – meustrus

+0

वास्तव में ऐसा लगता है कि 'ReentrantReadWriteLock' वास्तव में' सिंक्रनाइज़ 'से * बेहतर * प्रदर्शन कर सकता है, जब तक आप "निष्पक्ष" ताले का उपयोग नहीं करते हैं। ऐसा लगता है कि [सिंक्रनाइज़ किए गए 'और' रीन्टेंट्रॉक लॉक 'के बीच यह आईबीएम तुलना (http://www.ibm.com/developerworks/java/library/j-jtp10264/)। यद्यपि यह कुछ भी लायक नहीं है कि 'ReentrantLock'' ReentrantReadWriteLock 'जैसा नहीं है, यदि आपको ऐसा करने की आवश्यकता नहीं है तो आप पाठकों को क्यों लॉक कर देंगे? – meustrus

+0

इस दृष्टिकोण के साथ समस्या यह है कि पाठक एक साथ डेटास्ट्रक्चर को पढ़ नहीं सकते हैं, जबकि कई मामलों में, यह कोई समस्या नहीं है ... –

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