नॉन-ब्लॉकिंग रांगा

लिंक केलेल्या नोड्सवर थ्रेड-सेफ आणि सर्वात महत्त्वाचे म्हणजे नॉन-ब्लॉकिंग रांग अंमलबजावणी.

ConcurrentLinkedQueue<E> - हे कचरा गोळा करणाऱ्यांसोबत काम करण्यासाठी अनुकूल केलेले प्रतीक्षा-मुक्त अल्गोरिदम वापरते. हे अल्गोरिदम खूप कार्यक्षम आणि अतिशय जलद आहे, कारण ते CAS वर तयार केले आहे. साइज() पद्धतबराच काळ चालू शकते, त्यामुळे ती सतत न खेचणे चांगले.

ConcurrentLinkedDeque<E> - Deque म्हणजे Double ended queue. याचा अर्थ असा की डेटा जोडला जाऊ शकतो आणि दोन्ही बाजूंनी खेचला जाऊ शकतो. त्यानुसार, क्लास ऑपरेशनच्या दोन्ही पद्धतींना समर्थन देतो: 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 टाकते. कालबाह्यतेच्या आत रांगेत कोणताही घटक ठेवला नसल्यास मतदान पद्धत शून्य घटक परत करते.

ब्लॉकिंग रांग<E> अंमलबजावणी

चला आमच्या प्रत्येक ब्लॉकिंग रांग अंमलबजावणीवर बारकाईने नजर टाकूया :

ArrayBlockingQueue<E> हा क्लासिक रिंग बफरवर तयार केलेला ब्लॉकिंग क्यू वर्ग आहे. येथे आम्हाला लॉकची "प्रामाणिकता" व्यवस्थापित करण्याची संधी आहे. फेअर=फॉल्स (डीफॉल्ट) असल्यास, थ्रेड ऑर्डरिंगची हमी दिली जात नाही.

DelayQueue<E expends Delayed> हा एक वर्ग आहे जो तुम्हाला विलंबित इंटरफेसच्या getDelay पद्धतीद्वारे प्रत्येक घटकामध्ये ठराविक विलंबानंतरच घटक खेचण्याची परवानगी देतो.

LinkedBlockingQueue<E> लिंक केलेल्या नोड्सवर ब्लॉकिंग रांग आहे, जी “टू लॉक क्यू” अल्गोरिदमवर लागू केली जाते: पहिला लॉक जोडण्यासाठी आहे, दुसरा रांगेतून घटक खेचण्यासाठी आहे. लॉकमुळे, ArrayBlockingQueue च्या तुलनेत , या वर्गाची कार्यक्षमता उच्च आहे, परंतु त्याला अधिक मेमरी आवश्यक आहे. रांगेचा आकार कन्स्ट्रक्टरद्वारे सेट केला जातो आणि डीफॉल्टनुसार Integer.MAX_VALUE सारखा असतो.

PriorityBlockingQueue<E> हे PriorityQueue वर मल्टी-थ्रेडेड रॅपर आहे. ज्या तर्काने घटक जोडला जाईल त्यासाठी तुलनाकर्ता जबाबदार आहे. सर्वात लहान घटक प्रथम बाहेर येतो.

SynchronousQueue<E> - रांग FIFO (फर्स्ट-इन-फर्स्ट-आउट) तत्त्वानुसार कार्य करते. प्रत्येक इन्सर्ट ऑपरेशन "निर्माता" थ्रेडला ब्लॉक करते जोपर्यंत "ग्राहक" थ्रेड घटक रांगेतून खेचत नाही आणि त्याउलट, "निर्माता" घटक समाविष्ट करेपर्यंत "उपभोक्ता" प्रतीक्षा करेल.

BlockingDeque<E> हा एक इंटरफेस आहे जो द्विदिशात्मक ब्लॉकिंग रांगेसाठी अतिरिक्त पद्धतींचे वर्णन करतो. रांगेच्या दोन्ही बाजूंनी डेटा टाकला आणि बाहेर काढला जाऊ शकतो.

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

TransferQueue<E> - इंटरफेस मनोरंजक आहे की जेव्हा एखादा घटक रांगेत जोडला जातो, तेव्हाजोपर्यंत दुसरा ग्राहक थ्रेड घटक रांगेतून खेचत नाही तोपर्यंत समाविष्ट करणारा निर्माता थ्रेड अवरोधित करणे शक्य आहे. तुम्ही विशिष्ट कालबाह्यतेसाठी चेक देखील जोडू शकता किंवा प्रलंबित ग्राहकांसाठी चेक सेट करू शकता . परिणामी, आम्हाला एसिंक्रोनस आणि सिंक्रोनस संदेशांसाठी समर्थनासह डेटा ट्रान्सफर यंत्रणा मिळते.

LinkedTransferQueue<E> हे स्लॅक अल्गोरिदमसह दुहेरी रांगांवर आधारित हस्तांतरण रांगेची अंमलबजावणी आहेनिष्क्रिय असताना CAS (वर पहा) आणि थ्रेड पार्किंगचा प्रचंड वापर करते.