अस्वीकरण: मैं वास्तविक उत्पादन कोड में डीसीएल का उपयोग नहीं करता - मेरी केवल अकादमिक रुचि है।

मैंने निम्नलिखित प्रसिद्ध लेख पढ़ा है: "डबल-चेक्ड लॉकिंग है टूटा हुआ" घोषणा

समस्या की घोषणा (मेरी दृष्टि):

// Correct multithreaded version
class Foo { 
  private Helper helper = null;
  public synchronized Helper getHelper() {
    if (helper == null) 
        helper = new Helper();
    return helper;
    }
  // other functions and members...
  }

आइए कल्पना करें कि thread_1 निष्पादित लाइन helper = new Helper(); एक अन्य थ्रेड (thread_2) might देखें कि helper लिंक रिक्त नहीं है लेकिन इसे अभी तक प्रारंभ नहीं किया गया है। ऐसा इसलिए होता है क्योंकि helper लिंक असाइनमेंट के साथ कंस्ट्रक्टर इनवोकेशन को फिर से व्यवस्थित किया जा सकता है सेthread_2 दृश्य।

लेकिन इस आलेख में उल्लेख किया गया है कि यह दृष्टिकोण 32 बिट प्राइमेटिव के लिए ठीक से काम करता है।

हालांकि डबल-चेक किए गए लॉकिंग मुहावरे का उपयोग वस्तुओं के संदर्भ के लिए नहीं किया जा सकता है, यह 32-बिट आदिम मानों (जैसे, इंट या फ्लोट) के लिए काम कर सकता है। ध्यान दें कि यह लंबे या दोहरे के लिए काम नहीं करता है, क्योंकि 64-बिट प्राइमेटिव के अनसिंक्रनाइज़ किए गए पढ़ने/लिखने पर परमाणु होने की गारंटी नहीं है।

// Correct Double-Checked Locking for 32-bit primitives
class Foo { 
  private int cachedHashCode = 0;
  public int hashCode() {
    int h = cachedHashCode;
    if (h == 0) 
    synchronized(this) {
      if (cachedHashCode != 0) return cachedHashCode;
      h = computeHashCode();
      cachedHashCode = h;
      }
    return h;
    }
  // other functions and members...
  }

कृपया मुझे समझाएं कि यह क्यों काम करता है? मुझे पता है कि 32 बिट लिखना परमाणु है।

यहाँ स्थानीय चर का क्या कारण है?

1
gstackoverflow 19 सितंबर 2019, 16:27

1 उत्तर

सबसे बढ़िया उत्तर

"डीसीएल टूट गया है" ट्रोप का सार यह है कि, सिंगलटन ऑब्जेक्ट को प्रारंभ करने के लिए डीसीएल का उपयोग करके, एक थ्रेड ऑब्जेक्ट को पूरी तरह से प्रारंभिक स्थिति में देखने से पहले ऑब्जेक्ट का संदर्भ देख सकता है। DCL प्रभावी रूप से अंतिम वैश्विक चर को पर्याप्त रूप से सिंक्रनाइज़ करता है जो सिंगलटन को संदर्भित करता है, लेकिन यह सिंगलटन ऑब्जेक्ट को सिंक्रनाइज़ करने में विफल रहता है जिससे वैश्विक संदर्भित होता है।

आपके उदाहरण में, केवल वैश्विक चर है। कोई "वस्तु जिसके लिए यह संदर्भित करता है" नहीं है।

1
Solomon Slow 19 सितंबर 2019, 14:09