నాన్-బ్లాకింగ్ క్యూలు

లింక్ చేయబడిన నోడ్‌లలో థ్రెడ్-సేఫ్ మరియు ముఖ్యంగా నాన్-బ్లాకింగ్ క్యూ అమలులు.

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> అనేది క్లాసిక్ రింగ్ బఫర్‌పై నిర్మించిన బ్లాకింగ్ క్యూ క్లాస్. తాళాల "నిజాయితీ"ని నిర్వహించడానికి ఇక్కడ మనకు అవకాశం ఉంది. fair=false (డిఫాల్ట్) అయితే, థ్రెడ్ ఆర్డరింగ్ హామీ ఇవ్వబడదు.

DelayQueue<E విస్తరిస్తుంది ఆలస్యం> అనేది ఒక నిర్దిష్ట ఆలస్యం తర్వాత మాత్రమే క్యూ నుండి ఎలిమెంట్‌లను లాగడానికి మిమ్మల్ని అనుమతించే ఒక తరగతి, ప్రతి మూలకంలో ఆలస్యమైన ఇంటర్‌ఫేస్ యొక్క getDelay పద్ధతి ద్వారా నిర్వచించబడుతుంది .

LinkedBlockingQueue<E> అనేది లింక్ చేయబడిన నోడ్‌లలోని నిరోధించే క్యూ, ఇది “రెండు లాక్ క్యూ” అల్గారిథమ్‌లో అమలు చేయబడుతుంది: మొదటి లాక్ జోడించడం కోసం, రెండవది క్యూ నుండి ఒక మూలకాన్ని లాగడం కోసం. ArrayBlockingQueue తో పోలిస్తే లాక్‌ల కారణంగా, ఈ తరగతి అధిక పనితీరును కలిగి ఉంది, కానీ దీనికి ఎక్కువ మెమరీ అవసరం. క్యూ పరిమాణం కన్స్ట్రక్టర్ ద్వారా సెట్ చేయబడింది మరియు డిఫాల్ట్‌గా పూర్ణాంకం.MAX_VALUEకి సమానంగా ఉంటుంది.

PriorityBlockingQueue<E> అనేది PriorityQueue కంటే బహుళ-థ్రెడ్ రేపర్. మూలకం జోడించబడే తర్కానికి కంపారేటర్ బాధ్యత వహిస్తాడు. చిన్న మూలకం మొదట బయటకు వస్తుంది.

SynchronousQueue<E> - క్యూ FIFO (ఫస్ట్-ఇన్-ఫస్ట్-అవుట్) సూత్రం ప్రకారం పనిచేస్తుంది. ప్రతి ఇన్సర్ట్ ఆపరేషన్ "వినియోగదారు" థ్రెడ్‌ను క్యూ నుండి ఎలిమెంట్‌ని లాగే వరకు బ్లాక్ చేస్తుంది మరియు దీనికి విరుద్ధంగా, "నిర్మాత" మూలకాన్ని చొప్పించే వరకు "వినియోగదారు" వేచి ఉంటుంది.

BlockingDeque<E> అనేది ద్వి దిశాత్మక బ్లాకింగ్ క్యూ కోసం అదనపు పద్ధతులను వివరించే ఇంటర్‌ఫేస్. క్యూలో రెండు వైపుల నుండి డేటాను చొప్పించవచ్చు మరియు బయటకు తీయవచ్చు.

LinkedBlockingDeque<E> అనేది లింక్ చేయబడిన నోడ్‌లలో ద్విదిశాత్మక బ్లాకింగ్ క్యూ, ఇది ఒక లాక్‌తో సరళమైన ద్వి దిశాత్మక జాబితాగా అమలు చేయబడుతుంది. క్యూ పరిమాణం కన్స్ట్రక్టర్ ద్వారా సెట్ చేయబడింది మరియు డిఫాల్ట్‌గా పూర్ణాంకం.MAX_VALUEకి సమానంగా ఉంటుంది.

TransferQueue<E> - ఇంటర్‌ఫేస్ ఆసక్తికరంగా ఉంటుంది, దీనిలో ఒక మూలకం క్యూకి జోడించబడినప్పుడు, మరొక వినియోగదారు థ్రెడ్ మూలకాన్ని క్యూ నుండి లాగే వరకు చొప్పించే ప్రొడ్యూసర్ థ్రెడ్‌ను నిరోధించడం సాధ్యమవుతుందిమీరు నిర్దిష్ట గడువు ముగింపు కోసం చెక్‌ను కూడా జోడించవచ్చు లేదా పెండింగ్‌లో ఉన్న వినియోగదారుల కోసం చెక్‌ను సెట్ చేయవచ్చు . ఫలితంగా, మేము అసమకాలిక మరియు సమకాలిక సందేశాలకు మద్దతుతో డేటా బదిలీ విధానాన్ని పొందుతాము.

LinkedTransferQueue<E> అనేది స్లాక్ అల్గారిథమ్‌తో డ్యూయల్ క్యూల ఆధారంగా TransferQueue యొక్క అమలునిష్క్రియంగా ఉన్నప్పుడు CAS (పైన చూడండి) మరియు థ్రెడ్ పార్కింగ్‌ని ఎక్కువగా ఉపయోగిస్తుంది.