कंकरेंसी, ब्लॉकिंग क्यू (जावा 7) - 1

"हाय, अमीगो!"

"हाय, किम!"

"आज, मैं आपको संगामिति के बारे में बताने जा रहा हूँ।"

" Concurrency एक जावा क्लास लाइब्रेरी है जिसमें विशेष कक्षाएं शामिल हैं जिन्हें कई थ्रेड्स से काम करने के लिए अनुकूलित किया गया है। यह एक बहुत ही रोचक और व्यापक विषय है। लेकिन आज हम केवल एक परिचय प्राप्त करने जा रहे हैं। पैकेज को java.util कहा जाता है। समवर्ती पैकेज। मैं आपको कुछ दिलचस्प कक्षाओं के बारे में बताऊँगा।"

" परमाणु प्रकार। "

"आप पहले से ही जानते हैं कि काउंट++ भी थ्रेड-सेफ ऑपरेशन नहीं है। जब एक वेरिएबल को 1 से बढ़ाया जाता है, तो वास्तव में तीन ऑपरेशन होते हैं। परिणामस्वरूप, वेरिएबल को बदलने पर विरोध हो सकता है।"

"हाँ, ऐली ने मुझे बहुत पहले नहीं बताया था:"

थ्रेड 1 धागा 2 परिणाम
register1 = count;
register1++;
count = register1;
register2 = count;
register2++;
count = register2;
register1 = count;
register2 = count;
register2++;
count = register2;
register1++;
count = register1;

"बिल्कुल सही। फिर जावा ने इन कार्यों को एक के रूप में करने के लिए डेटा प्रकार जोड़े, यानी परमाणु रूप से (एक परमाणु अविभाज्य है)।"

"उदाहरण के लिए, जावा में AtomicInteger, AtomicBoolean, AtomicDouble , आदि हैं।"

"मान लीजिए कि हमें एक «काउंटर» क्लास बनाने की जरूरत है:"

उदाहरण
class Counter
{
 private int c = 0;

 public void increment()
 {
  c++;
 }

 public void decrement()
 {
  c--;
 }

 public int value()
 {
  return c;
 }
}

"आप इस वर्ग की वस्तुओं को थ्रेड-सुरक्षित कैसे बनाएंगे?"

"ठीक है, मैं सभी विधियों को सिंक्रनाइज़ करूँगा और इसके साथ किया जाएगा:"

उदाहरण
class synchronized Counter
{
 private int c = 0;

 public synchronized void increment()
 {
  c++;
 }

 public synchronized void decrement()
 {
  c--;
 }

 public synchronized int value()
 {
  return c;
 }
}

"अच्छा काम। लेकिन, अगर हम परमाणु प्रकार का इस्तेमाल करते हैं तो यह कैसा दिखेगा:"

उदाहरण
class AtomicCounter
{
 private AtomicInteger c = new AtomicInteger(0);

 public void increment()
 {
  c.incrementAndGet();
 }

 public void decrement()
 {
  c.decrementAndGet();
 }

 public int value()
 {
  return c.get();
 }
}

"आपकी कक्षा और मेरी कक्षा दोनों एक ही तरह से काम करती हैं, लेकिन एटॉमिक इंटेगर वाली कक्षा तेजी से काम करती है।"

"अच्छा, क्या यह एक छोटा सा अंतर है?"

"हां। मेरे अनुभव के आधार पर, मैं हमेशा सिंक्रनाइज़ के साथ अग्रणी होने की सलाह देता हूं। केवल जब सभी एप्लिकेशन कोड लिखे गए हैं और अनुकूलन प्रक्रिया शुरू हो गई है, तो आपको परमाणु प्रकारों का उपयोग करने के लिए कोड को फिर से लिखना शुरू करना चाहिए। लेकिन किसी भी मामले में, मैं आपको चाहता था यह जानने के लिए कि ऐसे प्रकार मौजूद हैं। यहां तक ​​कि अगर आप सक्रिय रूप से उनका उपयोग नहीं करते हैं, तो हमेशा एक मौका होता है कि आप कोड में चले जाएंगे जहां उनका उपयोग किया जाता है।"

"मैं सहमत हूँ। यह समझ में आता है।"

"वैसे, क्या आपने देखा कि परमाणु प्रकार अपरिवर्तनीय नहीं हैं? मानक पूर्णांक वर्ग के विपरीत , AtomicInteger में इसकी आंतरिक स्थिति को बदलने के तरीके शामिल हैं।"

"समझ गया। बिलकुल String और StringBuffer की तरह ।"

"हाँ कुछ ऐसा ही।"

" थ्रेड-सुरक्षित संग्रह। "

"इस तरह के संग्रह के उदाहरण के रूप में, क्या मैं ConcurrentHashMap प्रस्तुत कर सकता हूं। आप हैश मैप को थ्रेड-सुरक्षित कैसे बनायेंगे?"

"इसके सभी तरीकों को सिंक्रनाइज़ करें?"

"निश्चित रूप से, लेकिन अब कल्पना करें कि आपके पास एक ऐसा SynchronizedHashMap है, और इसे एक्सेस करने वाले दर्जनों थ्रेड्स हैं। और सौ बार एक सेकंड में एक नई प्रविष्टि मैप में जोड़ी जाती है, और इस प्रक्रिया में पूरी वस्तु पढ़ने और लिखने के लिए लॉक हो जाती है।"

"ठीक है, यह मानक तरीका है। आप क्या कर सकते हैं?"

"जावा के निर्माता कुछ अच्छी चीजों के साथ आए।"

"सबसे पहले, वे डेटा को एक ही ब्लॉक में समवर्ती हाशप में संग्रहीत करते हैं, लेकिन इसे 'बाल्टी' नामक भागों में विभाजित करते हैं। और जब कोई समवर्ती हाशप में डेटा बदलता है, तो हम केवल पूरे ऑब्जेक्ट के बजाय बकेट को एक्सेस किया जा रहा है। दूसरे में। शब्द, कई धागे वस्तु को एक साथ बदल सकते हैं।"

"दूसरा, क्या आपको याद है कि आप सूची/नक्शे के तत्वों पर पुनरावृति नहीं कर सकते हैं और एक ही समय में सूची को बदल सकते हैं? ऐसा कोड एक अपवाद फेंक देगा:"

एक लूप में एक संग्रह के तत्वों पर पुनरावृति न करें और साथ ही इसे बदलें
HashMap<String, Integer> map = new HashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"लेकिन ConcurrentHashMap में, आप यह कर सकते हैं:"

लूप में संग्रह के तत्वों पर पुनरावृति न करें और साथ ही इसे बदलें"
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"समवर्ती पैकेज के कई फायदे हैं। हमें इनका उपयोग करने के लिए इन वर्गों को अच्छी तरह से समझने की आवश्यकता है।"

"मैं समझ गया। धन्यवाद, किम। ये वास्तव में दिलचस्प कक्षाएं हैं। मुझे उम्मीद है कि किसी दिन मैं एक कलाप्रवीण व्यक्ति की तरह इसमें महारत हासिल कर लूंगा।"