2011-09-26 9 views
15

जेएमएम तर्क के अधिकांश में उपयोग किए जाने वाले किनारों से पहले परमाणु xX.lazySet (मान) विधि का क्या मतलब है? javadocs उस पर शुद्ध है, और सूर्य बग 6275329 कहता है:परमाणुXXX.lazySet (...) किनारों से पहले होता है

अर्थ विज्ञान है कि लिखने किसी भी पिछले लिखने के साथ पुनर्क्रमित होने की नहीं गारंटी है, लेकिन (या समतुल्य बाद से संचालित होने वाले पुनर्क्रमित किया जा सकता है, हो सकता है अन्य धागे के लिए दृश्यमान नहीं हो) जब तक कि कुछ अन्य अस्थिर लेखन या सिंक्रनाइज़िंग कार्रवाई नहीं होती)।

लेकिन यह एचबी किनारों के बारे में कोई तर्क नहीं है, इसलिए यह मुझे भ्रमित करता है। क्या इसका मतलब यह है कि एचबी किनारों के संदर्भ में आलसीसेट() अर्थशास्त्र व्यक्त नहीं किया जा सकता है?

अद्यतन: मैं अपने प्रश्न को ठोस बनाने की कोशिश करूंगा। ,

//thread 1: producer 
...fill some data structure 
myVolatileFlag = 1; 

//thread 2: consumer 
while(myVolatileFlag!=1){ 
    //spin-wait 
} 
...use data structure... 

"डेटा संरचना" के इस परिदृश्य प्रयोग में में उपभोक्ता सही है के बाद से अस्थिर झंडा लिखने-पढ़ने के लिए एचबी बढ़त बनाने के लिए, गारंटी दे रही है क्या सभी लेखन के लिए "डेटा संरचना: मैं इस परिदृश्य में साधारण अस्थिर क्षेत्र का उपयोग कर सकते "निर्माता द्वारा पूरा किया जाएगा, और उपभोक्ता द्वारा दिखाई देगा। लेकिन क्या होगा अगर मैं इस परिदृश्य में अस्थिर लिखने/पढ़ने के बजाय AtomicInteger.lazySet/प्राप्त करूंगा?

//thread 1: producer 
...fill some data structure 
myAtomicFlag.lazySet(1); 

//thread 2: consumer 
while(myAtomicFlag.get()!=1){ 
    //spin-wait 
} 
...use data structure... 

क्या यह अभी भी सही होगा? क्या मैं अभी भी उपभोक्ता धागे में "डेटा संरचना" मूल्य दृश्यता पर वास्तव में कर सकता हूं?

यह न सवाल "हवा से" है - मैं इस तरह के विधि LMAX Disruptor कोड में वास्तव में इस परिदृश्य में देखा है, और मुझे समझ नहीं आता कि यह सही है साबित करने के लिए कैसे ...

+0

अगर lazySet विधि दुकान-दुकान बाधा के रूप में कार्य करता है, यह उपयोग के लिए ठीक है। एक बार थ्रेड 2 ध्वज को देखता है तो यह संरचना को पढ़ने के लिए ठीक होगा। आलसीसेट सुनिश्चित करता है कि लेखन किसी बिंदु पर दिखाई देगा और सभी आर्किटेक्चर स्वचालित दृश्यता की अनुमति देते हैं, यानी यदि कुछ लिखा गया है तो यह दिखाई देगा और अंततः संगत होगा। – bestsss

उत्तर

10

lazySet संचालन किनारों से पहले नहीं होता है और इसलिए तुरंत दिखाई देने की गारंटी नहीं दी जाती है। यह एक निम्न स्तरीय अनुकूलन है जिसमें केवल कुछ उपयोग-मामले हैं, जो अधिकतर समवर्ती डेटा संरचनाओं में हैं।

लिंक किए गए सूची पॉइंटर्स को नल करने का कचरा संग्रहण उदाहरण कोई उपयोगकर्ता-दृश्य दुष्प्रभाव नहीं है। नलिंग को प्राथमिकता दी जाती है ताकि यदि सूची में नोड्स अलग-अलग पीढ़ियों में हों, तो यह लिंक श्रृंखला को त्यागने के लिए अधिक महंगा संग्रह करने के लिए मजबूर नहीं होता है।आलसी लिखने के ऊपर अस्थिर लिखने के बिना आलसी सैटैंटिक्स का उपयोग करता है।

एक अन्य उदाहरण है ऐसे ConcurrentHashMap में के रूप में एक ताला द्वारा सुरक्षित अस्थिर क्षेत्रों, के उपयोग है। फ़ील्ड लॉक-फ्री रीड की अनुमति देने के लिए अस्थिर हैं, लेकिन सख्त स्थिरता सुनिश्चित करने के लिए लिखना लॉक के नीचे किया जाना चाहिए। चूंकि लॉक रिलीज पर होने वाले पहले किनारे की गारंटी देता है, इसलिए ऑप्टिमाइज़ेशन फ़ील्ड पर लिखते समय आलसी सेट करते समय सभी अद्यतनों को फ़्लश करते समय आलसीकरण का उपयोग करना होता है। यह अनावश्यक स्टालों और बस यातायात से बचकर महत्वपूर्ण खंड को कम रखने में मदद करता है।

आप तो एक समवर्ती डेटा संरचना लिखते हैं lazySet एक अच्छा चाल के बारे में पता होना है। इसका निम्न स्तर का अनुकूलन इसलिए प्रदर्शन ट्यूनिंग पर विचार करने का एकमात्र मूल्य है।

+0

स्पष्टीकरण के लिए धन्यवाद। क्या आप अपडेट को भी देख सकते हैं और टिप्पणी कर सकते हैं? – BegemoT

+0

एक सेट के रूप में, एक कैस नहीं, यह केवल तभी सुरक्षित है जब यह दिखाई देने पर महत्वपूर्ण डेटा को ओवरराइट नहीं करेगा। एकाधिक उत्पादक स्लॉट के लिए प्रतिस्पर्धा करेंगे, इसलिए यह सुरक्षित नहीं है। यह सुरक्षित होगा अगर एक उपभोक्ता ने बफर को हटा दिया, मुफ्त स्लॉट की दृश्यता में देरी कर दी। मुझे लगता है कि के साथ खेल रहा था कुछ महीने पहले, मेरे [अंगूठी बफर] http://code.google.com/p/concurrentlinkedhashmap/source/browse/trunk/src/main/java/com/googlecode/concurrentlinkedhashmap/RingBuffer देखना (.java? spec = svn754 और r = 749) कोड। –

+0

यह एकल निर्माता/एकल उपभोक्ता मामला है। लेकिन मुझे अभी भी समझ में नहीं आ रहा है कि यह सुरक्षित क्यों है - मैं कैसे साबित कर सकता हूं कि 1) अनुक्रम से पहले क्या लिखा जाता है। LazySet (seq) सभी समाप्त हो गए हैं और _visible_ अनुक्रम के बाद थ्रेड 2 पर हैं .get() == seq? और क्या 2) आलसीसेट (सीईसी) वास्तव में कुछ सीमित समय पर लिखा जाता है: दस्तावेज़ "अंततः" कहते हैं - जिसका अर्थ "दूसरे में", "घंटे में" और यहां तक ​​कि "कभी नहीं" हो सकता है। अगर आलसी अस्थिर लिखने के रूप में आलसी सेट पर देखें तो ऐसा लगता है कि यह संकलक या प्रोसेसर द्वारा हमेशा के लिए देरी हो सकती है ... – BegemoT

3

के आधार पर असुरक्षित के जावाडोक (putOrderedInt AtomicInteger.lazySet में प्रयोग किया जाता है)

/** 
* Version of {@link #putObjectVolatile(Object, long, Object)} 
* that does not guarantee immediate visibility of the store to 
* other threads. This method is generally only useful if the 
* underlying field is a Java volatile (or if an array cell, one 
* that is otherwise only accessed using volatile accesses). 
*/ 
public native void putOrderedObject(Object o, long offset, Object x); 

/** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */ 
public native void putOrderedInt(Object o, long offset, int x); 

AtomicXXX कक्षाओं में समर्थन क्षेत्रों अस्थिर कर रहे हैं। आलसीसेट इन क्षेत्रों में लिखना प्रतीत होता है जैसे कि वे अस्थिर नहीं हैं, जो आपके द्वारा अपेक्षा की जाने वाली पूर्व-किनारों को हटा देगा। जैसा कि आपके लिंक में उल्लेख किया गया है, यह अस्थिर लेखन करने के बिना जीसी के लिए पात्र होने के लिए मूल्यों को कम करने के लिए उपयोगी होगा।

संपादित करें:

यह आपके अद्यतन जवाब देने के लिए है।

यदि आप लिंक से प्रदान किए गए उद्धरण पर नज़र डालें तो आप अस्थिर लेखन के साथ किसी भी स्मृति गारंटी को खो देते हैं।

आलसीसेट को ऊपर से आदेश नहीं दिया जाएगा जहां इसे लिखा जा रहा है, लेकिन बिना किसी अन्य वास्तविक सिंक्रनाइज़ेशन के आप इस गारंटी को खो देते हैं कि उपभोक्ता को इससे पहले कि कोई भी बदलाव दिखाई देगा। MyAtomicFlag के लिखने में देरी करना और इसके पहले किसी भी प्रकार के लिखने के लिए यह पूरी तरह से कानूनी है जब तक सिंक्रनाइज़ेशन का कोई अन्य रूप नहीं होता है।

+0

आलसी सेट कोई लिखने की पुनरावृत्ति सुनिश्चित नहीं करता है, लेकिन इसे पढ़ने के लिए ऐसा न करें, यानी मान को प्रसारित करने से पहले लगातार पढ़ा जा सकता है। x86 lazySet के लिए सिर्फ एक mov निर्देश है। ऊपर दिए गए उदाहरण में, आलसी सेट ठीक है, इमो ... और यह बहुत अच्छी जीत है। – bestsss

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