8

में समवर्ती हैशैप की अलग-अलग 'अगली' प्रविष्टि जेडीके 1.6 में, डौग ली फ़ील्ड से पहले final का उपयोग करती है।जेडीके 1.6 और जेडीके 1.7

static final class HashEntry<K,V> { 
    final K key; 
    final int hash; 
    volatile V value; 
    final HashEntry<K,V> next; 

JDK 1.7 में जबकि, next क्षेत्र volatile से पहले किया गया है। मैं यह भी ध्यान देता हूं कि जेडीके 1.7 में, get विधि value फ़ील्ड पढ़ने के लिए getObjectVolatile विधि को गोद लेती है, जिसमें अस्थिर लोड अर्थशास्त्र है।

मुझे कोई समझ नहीं है कि क्यों डौग ली पहले final का उपयोग करता है। अगर शुद्धता में समस्याएं हैं, तो वह जेडीके 1.7 (जेडीके 1.8) में volatile के साथ इसे कैसे बदल सकता है?

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

विशेष रूप से, मेरे सवाल है कि हम JDK 1.6 के क्रियान्वयन में volatile साथ final बदल सकते है?

+1

यह कक्षा जावा 8 में सीएचएम में नहीं है। – assylias

+1

ठीक है, अगर यह आपका प्रश्न है, तो नहीं, आप नहीं कर सकते। संशोधक को बदलने का कारण यह है कि कार्यान्वयन पूरी तरह से बदला गया था। यह एक अलग परिवर्तन नहीं है। – RealSkeptic

+1

@ रीयलस्केप्टिक, क्या आप स्पष्टीकरण के लिए कुछ विवरण, या लेख प्रस्तुत कर सकते हैं? धन्यवाद। –

उत्तर

2

अपने पहले प्रश्न के लिए:

मैं कोई मतलब नहीं क्यों डौग ली पहले से अंतिम उपयोग करता है। यदि सहीता के साथ समस्याएं हैं, तो वह जेडीके 1.7 (जेडीके 1.8) में अस्थिर के साथ इसे कैसे बदल सकता है?

यह शुद्धता का मामला नहीं था। थ्रेड-सुरक्षा के मामले में दोनों कार्यान्वयन सही हैं। हल करने की कोशिश कर रहा था सीएचएम के शुरुआती पदचिह्न को कम कर रहा था। जावा 6 में, next फ़ील्ड फ़ाइनल बनाने के लिए ऑब्जेक्ट कम से कम एक प्लेसहोल्डर के साथ बनाया जाना आवश्यक था। इससे अत्यधिक खाली ऑब्जेक्ट सृजन हुआ और इसलिए जब आवश्यक-आवश्यक अर्थशास्त्र बनाने की पेशकश की गई तो इसे बदल दिया गया।

विशेष रूप से, मेरा सवाल यह है कि क्या हम जेडीके 1.6 के कार्यान्वयन में अस्थिर के साथ फाइनल को प्रतिस्थापित कर सकते हैं?

निश्चित रूप से जब तक संचालन अनुक्रमिक रूप से सुसंगत रहेगा, जो वे हैं।


डौग ली की टिप्पणी छूता है की इस डिजाइन परिवर्तन

/* 
* ... 
* Historical note: The previous version of this class relied 
* heavily on "final" fields, which avoided some volatile reads at 
* the expense of a large initial footprint. Some remnants of 
* that design (including forced construction of segment 0) exist 
* to ensure serialization compatibility. 
*/ 

तो एक और सवाल आप शायद कर रहे हैं जवाब देने के लिए पर एक, क्यों final शुरू में चुना गया था? बाद में कुछ अस्थिर पढ़ने को रोकने के लिए।

+0

मेरे पास एक ही विचार है, लेकिन मैं इसे स्वयं से पुष्टि नहीं कर सकता। मुझे आश्चर्य है कि क्या आप जावा एपीआई के बारे में समान प्रश्नों के साथ आते हैं, तो आप उन्हें कैसे संभालेंगे? धन्यवाद। –

0

final को volatile के साथ बदलने की बात नहीं है। RealSkeptic की तरह यह कई अन्य तरीकों के बीच बदला गया था। उद्देश्य ConcurrentHashMap.remove() का अनुकूलन हो सकता है। जेडीके 1.6 में बाल्टी (हैशकोड द्वारा समूहीकृत वस्तुओं) को स्टोर करने वाली सूची कॉपीऑनवाइट है, इसलिए remove() सूची के भाग की प्रतिलिपि बनाई गई है, जेडीके 1.7 में केवल next पॉइंटर बदल गया है।

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