गैर-अवरुद्ध कतारें

लिंक किए गए नोड्स पर थ्रेड-सुरक्षित और सबसे महत्वपूर्ण गैर-अवरुद्ध कतार कार्यान्वयन।

ConcurrentLinkedQueue<E> - यह कचरा संग्राहक के साथ काम करने के लिए अनुकूलित प्रतीक्षा-मुक्त एल्गोरिदम का उपयोग करता है। यह एल्गोरिथम काफी कुशल और बहुत तेज है, क्योंकि यह CAS पर बनाया गया है। आकार () विधिलंबे समय तक चल सकती है, इसलिए इसे हर समय नहीं खींचना सबसे अच्छा है।

ConcurrentLinkedDeque<E> - Deque का मतलब डबल एंडेड क्यू है। इसका मतलब है कि डेटा को दोनों तरफ से जोड़ा और खींचा जा सकता है। तदनुसार, वर्ग ऑपरेशन के दोनों तरीकों का समर्थन करता है: FIFO (फर्स्ट इन फर्स्ट आउट) और LIFO (लास्ट इन फर्स्ट आउट)।

व्यवहार में, यदि LIFO बिल्कुल आवश्यक है, तो ConcurrentLinkedDeque का उपयोग किया जाना चाहिए, क्योंकि नोड्स की द्विदिशता के कारण, यह वर्ग ConcurrentLinkedQueue की तुलना में प्रदर्शन में आधा खो देता है ।

import java.util.concurrent.ConcurrentLinkedQueue;

public class  ConcurrentLinkedQueueExample {
   public static void main(String[] args) {
       ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();

       Thread producer = new Thread(new Producer(queue));
       Thread consumer = new Thread(new Consumer(queue));

       producer.start();
       consumer.start();
   }
}

class Producer implements Runnable {

   ConcurrentLinkedQueue<String> queue;
   Producer(ConcurrentLinkedQueue<String> queue){
       this.queue = queue;
   }
   public void run() {
       System.out.println("Class for adding items to the queue");
       try {
           for (int i = 1; i < 5; i++) {
               queue.add("Item #" + i);
               System.out.println("Added: Item #" + i);
               Thread.sleep(300);
           }
       } catch (InterruptedException ex) {
           ex.printStackTrace();
           Thread.currentThread().interrupt();
       }
   }
}

class Consumer implements Runnable {

   ConcurrentLinkedQueue<String> queue;
   Consumer(ConcurrentLinkedQueue<String> queue){
       this.queue = queue;
   }

   public void run() {
       String str;
       System.out.println("Class for getting items from the queue");
       for (int x = 0; x < 5; x++) {
           while ((str = queue.poll()) != null) {
               System.out.println("Pulled out: " + str);
           }
           try {
               Thread.sleep(600);
           } catch (InterruptedException ex) {
               ex.printStackTrace();
               Thread.currentThread().interrupt();
           }
       }
   }
}

अवरुद्ध कतारें

BlockingQueue<E> इंटरफ़ेस -यदि बहुत अधिक डेटा है, तो ConcurrentLinkedQueue पर्याप्त नहीं है।

जब धागे अपना काम करने में विफल होते हैं, तो आप आसानी से OutOfMemmoryException प्राप्त कर सकते हैं । और ताकि ऐसे मामले उत्पन्न न हों, हमारे पास कतार और सशर्त तालों को भरने और काम करने के लिए विभिन्न तरीकों की उपस्थिति के साथ काम करने के लिए एक ब्लॉकिंग क्यू है।

BlockingQueue अशक्त तत्वों को नहीं पहचानता है औरइस तरह के तत्व को जोड़ने या प्राप्त करने का प्रयास करते समय एक NullPointerException फेंकता है। यदि टाइमआउट के भीतर कतार में कोई तत्व नहीं रखा गया है, तो पोल विधि एक अशक्त तत्व लौटाती है।

BlockingQueue<E> कार्यान्वयन

आइए हमारे प्रत्येक BlockingQueue कार्यान्वयन पर करीब से नज़र डालें :

ArrayBlockingQueue<E> क्लासिक रिंग बफर पर निर्मित एक ब्लॉकिंग क्यू क्लास है। यहां हमारे पास तालों की "ईमानदारी" का प्रबंधन करने का अवसर है। यदि उचित = गलत (डिफ़ॉल्ट), तो थ्रेड ऑर्डरिंग की गारंटी नहीं है।

DelayQueue<E विस्तारित विलंबित> एक वर्ग है जो आपको विलंबित इंटरफ़ेस की getDelay विधि के माध्यम से प्रत्येक तत्व में परिभाषित एक निश्चित विलंब के बाद ही कतार से तत्वों को खींचने की अनुमति देता है ।

LinkedBlockingQueue<E> लिंक किए गए नोड्स पर एक अवरुद्ध कतार है, जिसे "दो लॉक कतार" एल्गोरिथम पर लागू किया गया है: पहला लॉक जोड़ने के लिए है, दूसरा कतार से तत्व खींचने के लिए है। ताले के कारण, ArrayBlockingQueue की तुलना में , इस वर्ग का प्रदर्शन उच्च है, लेकिन इसके लिए अधिक मेमोरी की आवश्यकता होती है। कतार का आकार कंस्ट्रक्टर के माध्यम से सेट किया गया है और डिफ़ॉल्ट रूप से Integer.MAX_VALUE के बराबर है।

प्रायोरिटीब्लॉकिंग क्यू <ई> प्रायोरिटी क्यू पर एक बहु-थ्रेडेड आवरण है। तुलनित्र तर्क के लिए ज़िम्मेदार है जिसके द्वारा तत्व जोड़ा जाएगा। सबसे छोटा तत्व पहले बाहर आता है।

तुल्यकालिक कतार <ई> - कतार फीफो (पहले-में-पहले-बाहर) सिद्धांत के अनुसार काम करती है। प्रत्येक सम्मिलन ऑपरेशन "निर्माता" थ्रेड को तब तक ब्लॉक करता है जब तक "उपभोक्ता" थ्रेड तत्व को कतार से नहीं खींचता है और इसके विपरीत, "उपभोक्ता" तब तक प्रतीक्षा करेगा जब तक "निर्माता" तत्व को सम्मिलित नहीं करता।

BlockingDeque<E> एक इंटरफ़ेस है जो द्विदिश ब्लॉकिंग कतार के लिए अतिरिक्त विधियों का वर्णन करता है। कतार के दोनों ओर से डेटा डाला और निकाला जा सकता है।

LinkedBlockingDeque<E> लिंक किए गए नोड्स पर एक द्विदिश अवरोधक कतार है, जिसे एक लॉक के साथ सरल द्विदिश सूची के रूप में लागू किया गया है। कतार का आकार कंस्ट्रक्टर के माध्यम से सेट किया गया है और डिफ़ॉल्ट रूप से Integer.MAX_VALUE के बराबर है।

TransferQueue<E> - इंटरफ़ेस दिलचस्प है कि जब कोई तत्व कतार में जोड़ा जाता है, तो सम्मिलित निर्माता थ्रेड को तब तक ब्लॉक करना संभव है जब तक कि कोई अन्य उपभोक्ता थ्रेड कतार से तत्व को खींच नहीं लेता। आप किसी विशिष्ट टाइमआउट के लिए चेक भी जोड़ सकते हैं या लंबित उपभोक्ता के लिए चेक सेट कर सकते हैं । नतीजतन, हमें अतुल्यकालिक और तुल्यकालिक संदेशों के समर्थन के साथ एक डेटा ट्रांसफर तंत्र मिलता है।

LinkedTransferQueue<E> स्लैक एल्गोरिथम के साथ दोहरी कतारों के आधार पर TransferQueue का कार्यान्वयन हैनिष्क्रिय होने पर सीएएस (ऊपर देखें) और थ्रेड पार्किंग का भारी उपयोग करता है।