2011-12-08 11 views
7

इस सवाल का कई जवाब में सुझाव दिया गया है:क्या रीडवाइट लॉक सिंक्रनाइज़ किए गए कीवर्ड को अनावश्यक प्रस्तुत करता है?

What is the name of this locking technique?

मैं एक ReentrantReadWriteLock लागू किया है और एक महान speedup देखा (मुझे पता था कि एक मेरी कक्षा में कुछ लॉक विवाद और एक रैत्रांत ताला मदद गति बातें किया था का उपयोग कर रही थी तक)।

लेकिन अब मैं सोच रहा हूँ: अगर सब पहुँच एक क्लास के भीतर (दोनों रीड और राईट) पहले या तो एक पढ़ा-लॉक या एक लेख ताला ताला लगा द्वारा किया जाता है, इसका मतलब यह है सिंक्रनाइज़ कीवर्ड नहीं होना चाहिए उस वर्ग में अब और इस्तेमाल किया?

उदाहरण के लिए, यहाँ एक आधिकारिक जावा 1.6 उदाहरण http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html

class RWDictionary { 
    private final Map<String, Data> m = new TreeMap<String, Data>(); 
    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 
    private final Lock r = rwl.readLock(); 
    private final Lock w = rwl.writeLock(); 

    public Data get(String key) { 
     r.lock(); 
     try { return m.get(key); } 
     finally { r.unlock(); } 
    } 
    public String[] allKeys() { 
     r.lock(); 
     try { return m.keySet().toArray(); } 
     finally { r.unlock(); } 
    } 
    public Data put(String key, Data value) { 
     w.lock(); 
     try { return m.put(key, value); } 
     finally { w.unlock(); } 
    } 
    public void clear() { 
     w.lock(); 
     try { m.clear(); } 
     finally { w.unlock(); } 
    } 
} 

में पाया कोई सिंक्रनाइज़ कीवर्ड है।

अब मुझे एहसास है कि इस तरह के ताले के बिंदु में से एक अन्य तरीकों से तेज़ होना है (इस मामले में सिंक्रनाइज़ करें) लेकिन इसके पीछे तकनीकी स्पष्टीकरण क्या है?

क्या प्रत्येक विधि/अद्यतन विधि में एक वर्ग में रीड-राइट लॉक का उपयोग इन विधियों के लिए कीवर्ड सिंक्रनाइज़ करता है?

+0

मुझे लगता है कि आप उदाहरण पर सिंक्रनाइज़ कर रहे थे, जैसे 'सिंक्रनाइज़ (यह)'। इसके बजाए, यदि आप दो अलग-अलग ऑब्जेक्ट्स पर सिंक्रनाइज़ करते हैं, तो पढ़ने के लिए और एक लिखने के लिए, आप एक ही प्रदर्शन प्राप्त कर लेते। 'इस 'सिंक के साथ, जब' put' संसाधित किया जा रहा है, अनावश्यक रूप से 'get' भी प्रतीक्षा करने के लिए बनाया जाता है। विभिन्न लॉकिंग ऑब्जेक्ट्स के साथ, यह विवाद दूर हो जाता है। – srkavin

+0

अधिकांश नक्शा कार्यान्वयन के लिए यह * प्रगति पर है, जबकि प्रतीक्षा करने के लिए आवश्यक है *। – Affe

+0

@srkavin विवाद दूर हो गया होगा, लेकिन स्मृति दृश्यता की गारंटी भी होगी। आपके 'get'' को 'put' से आंशिक अपडेट देखा होगा, क्योंकि वे एक-दूसरे के सापेक्ष सिंक्रनाइज़ नहीं किए गए थे। – yshavit

उत्तर

10

तुम ReadWriteLock पर javadocs पढ़ा है, और लॉक की, वे विशेष रूप से कहना है कि ताले synchronized कीवर्ड के समान स्मृति अर्थ विज्ञान प्रदान करने के लिए है, तो:

सभी लॉक कार्यान्वयन के रूप में ही स्मृति तुल्यकालन अर्थ विज्ञान को लागू करना चाहिए (।; ReadWriteLock इसके सिमेंटिक वर्णन करने के लिए लॉक को संदर्भित करता है कि ताला जावाडोक से है)

: द्वारा, बिल्ट-इन पर नजर रखने के ताला जावा भाषा विशिष्टता, तीसरा संस्करण (17.4 मेमोरी मॉडल) में वर्णित के रूप में प्रदान 012,

तो, हाँ, यह synchronized कीवर्ड को प्रतिस्थापित करता है। वास्तव में, आप लॉक के साथ अपने कोड में प्रत्येक synchronized ब्लॉक को प्रतिस्थापित कर सकते हैं और समान अर्थशास्त्र (और, जेवीएम के आधार पर, संभवतः यहां तक ​​कि एक छोटा प्रदर्शन बढ़ावा भी हो सकता है।) लेकिन आप बहुत अधिक गतिशीलता के लिए थोड़ा सा गति व्यापार करेंगे , और यदि आप कभी भी उन ताले में से किसी एक को अनलॉक करना भूल जाते हैं, तो आप अपने प्रोग्राम को डेडलॉक कर सकते हैं।

क्या शक्तियां इस का एक बहुत nonblocking एल्गोरिदम है (compare-and-swap किया जा रहा है उनमें से दिल) volatile क्षेत्रों की स्मृति अर्थ विज्ञान है, जो कि यदि आप एक volatile क्षेत्र के लिए लिखते हैं, किसी भी धागा है कि बाद में उस क्षेत्र पढ़ता गया है निर्दिष्ट के साथ संयुक्त जब आपने इसे लिखा था तब कम से कम दुनिया की एक ही स्थिति देखें। (वे कुछ लिखने के बाद कुछ या सब कुछ भी देख सकते थे।) वे उपकरण कुछ सुंदर फास्ट कोड के लिए बना सकते हैं, लेकिन वे भी सूक्ष्म और गलत होने में आसान हैं - उच्च स्तर के साथ रहना लगभग हमेशा सर्वोत्तम होता है संरचनाएं (जैसे रीडवाइट लॉक आप उपयोग कर रहे हैं)।

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

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