The

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

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

"मैं एक छोटे से उदाहरण के साथ शुरू करूँगा। मान लीजिए कि हमारे पास एक सर्वर के लिए एक प्रोग्राम है जो एक वेबसाइट के माध्यम से उपयोगकर्ताओं द्वारा बनाए गए विभिन्न कार्यों को पूरा करता है। उपयोगकर्ता अलग-अलग समय पर विभिन्न कार्यों को जोड़ सकते हैं। कार्य संसाधन-गहन हैं, लेकिन हमारे सर्वर के 8 -कोर प्रोसेसर सामना कर सकता है। हमें सर्वर पर कार्य कैसे करना चाहिए?"

"सबसे पहले, हम वर्कर थ्रेड्स का एक समूह बनाएंगे, जितने प्रोसेसर कोर हैं। प्रत्येक थ्रेड अपने स्वयं के कोर पर चलने में सक्षम होगा: थ्रेड्स एक दूसरे के साथ हस्तक्षेप नहीं करेंगे, और प्रोसेसर कोर नहीं होंगे। बेकार बैठो।"

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

"क्या आप मुझे कार्य वस्तु का उदाहरण दे सकते हैं?"

"इसकी जांच - पड़ताल करें:"

एक वर्ग जो रन () विधि कहलाते समय एन फैक्टोरियल की गणना करता है
class Factorial implements Runnable
{
 public int n = 0;
 public long result = 1;

 public Factorial (int n)
 {
  this.n = n;
 }

 public void run()
 {
  for (int i = 2; i <= n; i++)
   result *= i;
 }
}

"अब तक तो सब ठीक है।"

"बहुत बढ़िया। फिर देखते हैं कि क्यू ऑब्जेक्ट कैसा दिखना चाहिए। आप मुझे इसके बारे में क्या बता सकते हैं?"

"यह थ्रेड-सुरक्षित होना चाहिए। यह टास्क ऑब्जेक्ट्स के साथ एक थ्रेड द्वारा लोड किया जाता है जो उन्हें उपयोगकर्ताओं से प्राप्त करता है, और फिर वर्कर थ्रेड्स द्वारा कार्यों को उठाया जाता है।"

"हाँ। और क्या होगा अगर हम कुछ समय के लिए काम से बाहर हो जाएं?"

"फिर कार्यकर्ता धागे को और अधिक होने तक इंतजार करना चाहिए।"

"यह सही है। अब कल्पना कीजिए कि यह सब एक कतार में बनाया जा सकता है। इसे देखें:"

एक कार्य कतार। यदि कोई कार्य नहीं है, तो धागा सो जाता है और किसी के प्रकट होने की प्रतीक्षा करता है:
public class JobQueue
{
 ArrayList jobs = new ArrayList();

 public synchronized void put(Runnable job)
 {
  jobs.add(job);
  this.notifyAll();
 }

 public synchronized Runnable getJob()
 {
  while (jobs.size() == 0)
   this.wait();

  return jobs.remove(0);
 }
}

"हमारे पास एक गेटजॉब विधि है जो जांचती है कि कार्य सूची खाली है या नहीं। सूची में कुछ दिखाई देने तक थ्रेड सो जाता है (प्रतीक्षा करता है)। "

" पुट विधि भी है , जो आपको सूची में एक नया कार्य जोड़ने देती है। जैसे ही कोई नया कार्य जोड़ा जाता है, InformAll विधि को कॉल किया जाता है। इस विधि को कॉल करने से सभी वर्कर थ्रेड जाग जाते हैं जो GetJob विधि के अंदर सो गए थे।"

"क्या आप फिर से याद कर सकते हैं कि प्रतीक्षा और सूचना के तरीके कैसे काम करते हैं?"

"प्रतीक्षा विधि केवल एक म्यूटेक्स ऑब्जेक्ट पर एक सिंक्रनाइज़ ब्लॉक के अंदर ही बुलाई जाती है। हमारे मामले में: यह। इसके अलावा, दो चीजें होती हैं:

1) धागा सो जाता है।

2) थ्रेड अस्थायी रूप से म्यूटेक्स जारी करता है (जब तक यह जाग नहीं जाता)।

"उसके बाद, अन्य धागे सिंक्रनाइज़ किए गए ब्लॉक में प्रवेश कर सकते हैं और उसी म्यूटेक्स को प्राप्त कर सकते हैं।"

" InformAll मेथड को केवल एक म्यूटेक्स ऑब्जेक्ट के सिंक्रोनाइज़्ड ब्लॉक के अंदर ही कॉल किया जा सकता है। हमारे मामले में: यह। इसके अलावा, दो चीजें होती हैं:"

1) इस म्यूटेक्स ऑब्जेक्ट पर प्रतीक्षा कर रहे सभी थ्रेड्स जागृत हैं।

2) एक बार जब वर्तमान थ्रेड सिंक्रोनाइज़्ड ब्लॉक से बाहर निकल जाता है, तो जागृत थ्रेड्स में से एक म्यूटेक्स प्राप्त कर लेता है और अपना काम जारी रखता है। जब यह म्यूटेक्स जारी करता है, तो एक अन्य जागृत धागा म्यूटेक्स आदि को प्राप्त कर लेता है।

"यह एक बस के समान है। आप प्रवेश करते हैं और अपना किराया देना चाहते हैं, लेकिन कोई ड्राइवर नहीं है। इसलिए आप 'सो जाते हैं'। आखिरकार, बस भरी हुई है, लेकिन किराया देने के लिए अभी भी कोई नहीं है। आता है और कहता है, «किराया, कृपया»। और यह शुरुआत है ..."

"दिलचस्प तुलना। लेकिन बस क्या है?"

"जूलियो ने इसे समझाया। 21 वीं सदी में इस्तेमाल की जाने वाली ये अजीब चीजें थीं।"