2012-03-21 17 views
5

क्या यह कक्षा थ्रेड-सुरक्षित है?परमाणु इंटेगर बनाम सिंक्रनाइज़ गेटर्स/सेटर्स

क्या असंगत मूल्य देखना संभव है? आइए शुरुआती रूप से एक मूल्य 80 है। थ्रेड 1 कॉल setA(100) और फ़ंक्शन में प्रवेश करता है लेकिन अभी तक a.set(100) पर कॉल नहीं किया गया है और थ्रेड 2 समवर्ती रूप से getA() पर कॉल करता है। क्या थ्रेड 2 के लिए 80 देखना संभव है?

public class A { 
    private AtomicInteger a; 

    public int getA() { 
     return a.get() 
    } 

    public void setA(int newVal){ 
     a.set(newVal); 
    } 
} 

मुझे पता है कि सिंक्रनाइज़ किया जा रहा यह धागा 2 की गारंटी देगा देखता है 100, लेकिन AtomicInteger साथ यकीन नहीं।

उत्तर

9

क्या यह कक्षा थ्रेड-सुरक्षित है?

हां यह है।

थ्रेड 1 कॉल सेटए (100) और फ़ंक्शन में प्रवेश करता है लेकिन अभी तक एक .set (100) और थ्रेड 2 को कॉल नहीं करता है, साथ ही getA() को कॉल करता है। क्या थ्रेड 2 के लिए 80 देखना संभव है?

हां। स्मृति बाधा कोड है कि अंदर की AtomicInteger पूरा करता अस्थिर क्षेत्र synchronizes तक, रेस स्थिति दिखा सकते हैं 80 या 100

थ्रेड 1 भी AtomicInteger.set विधि प्रवेश कर सकता है और भीतरी क्षेत्र असाइनमेंट से पहले हो सकता है और अभी भी 80 लौटाया जा सकता है AtomicInteger.get विधि प्राप्त करके।

के बारे में कोई गारंटी नहीं है जब मान अन्य धागे में अपडेट किए जाएंगे। गारंटी है कि get() पूर्ण हो जाता है, आपको सबसे हालिया सिंक्रनाइज़ मान मिलता है और जब set() पूर्ण हो जाता है, तो अन्य सभी थ्रेड अपडेट देखेंगे।

समय को गेटटर और सेटटर कॉल के अलग-अलग धागे में कोई गारंटी नहीं है।

1

जैसा कि @ ग्रे ने नोट किया है, यहां दौड़ की स्थिति की संभावना है।

get पर कॉल करना और फिर set परमाणु ऑपरेशन नहीं है। The Atomic* classes लॉक-फ्री परमाणु सशर्त अद्यतन ऑपरेशन, compareAndSet प्रदान करता है - आपको उस थ्रेड सुरक्षा के लिए उपयोग करना चाहिए।

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