Hindi Naka-block na Mga Pila

Ligtas sa thread at ang pinakamahalaga ay hindi naka-block na mga pagpapatupad ng Queue sa mga naka-link na node.

ConcurrentLinkedQueue<E> - gumagamit ito ng algorithm na walang paghihintay na inangkop upang gumana sa tagakolekta ng basura. Ang algorithm na ito ay medyo mahusay at napakabilis, dahil ito ay binuo sa CAS. Ang size() na pamamaraanay maaaring tumakbo nang mahabang panahon, kaya pinakamahusay na huwag hilahin ito sa lahat ng oras.

ConcurrentLinkedDeque<E> - Ang Deque ay nangangahulugang Double ended queue. Nangangahulugan ito na ang data ay maaaring idagdag at makuha mula sa magkabilang panig. Alinsunod dito, sinusuportahan ng klase ang parehong mga mode ng pagpapatakbo: FIFO (First In First Out) at LIFO (Last In First Out).

Sa pagsasagawa, dapat gamitin ang ConcurrentLinkedDeque kung talagang kinakailangan ang LIFO, dahil dahil sa bidirectionality ng mga node, ang klase na ito ay nawawalan ng kalahati sa performance kumpara sa 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();
           }
       }
   }
}

Pag-block ng Mga Pila

Interface ng BlockingQueue<E> - kung maraming data, hindi sapat ang ConcurrentLinkedQueue .

Kapag nabigo ang mga thread na gawin ang kanilang trabaho, madali kang makakakuha ng OutOfMemmoryException . At upang ang mga ganitong kaso ay hindi lumabas, mayroon kaming BlockingQueue para sa trabaho na may pagkakaroon ng iba't ibang mga pamamaraan para sa pagpuno at pagtatrabaho sa queue at mga conditional lock.

Ang BlockingQueue ay hindi nakikilala ang mga null na elemento at nagtatapon ng NullPointerException kapag sinusubukang magdagdag o kumuha ng ganoong elemento. Ang pamamaraan ng poll ay nagbabalik ng isang null na elemento kung walang elementong inilagay sa pila sa loob ng timeout.

Mga Pagpapatupad ng BlockingQueue<E>

Tingnan natin ang bawat isa sa aming mga pagpapatupad ng BlockingQueue :

Ang ArrayBlockingQueue<E> ay isang blocking queue class na binuo sa classic ring buffer. Dito mayroon kaming pagkakataon na pamahalaan ang "katapatan" ng mga kandado. Kung fair=false (ang default), hindi garantisado ang pag-order ng thread.

Ang DelayQueue<E extends Delayed> ay isang klase na nagbibigay-daan sa iyong hilahin ang mga elemento mula sa queue pagkatapos lamang ng isang partikular na pagkaantala, na tinukoy sa bawat elemento sa pamamagitan ng getDelay na paraan ng Delayed interface.

Ang LinkedBlockingQueue<E> ay isang blocking queue sa mga naka-link na node, na ipinatupad sa "two lock queue" algorithm: ang unang lock ay para sa pagdaragdag, ang pangalawa ay para sa paghila ng elemento mula sa queue. Dahil sa mga lock, kumpara sa ArrayBlockingQueue , ang klase na ito ay may mataas na pagganap, ngunit nangangailangan ito ng mas maraming memorya. Ang laki ng pila ay itinakda sa pamamagitan ng constructor at katumbas ng Integer.MAX_VALUE bilang default.

Ang PriorityBlockingQueue<E> ay isang multi-threaded wrapper sa ibabaw ng PriorityQueue . Ang Comparator ay responsable para sa lohika kung saan idaragdag ang elemento. Ang pinakamaliit na elemento ay unang lumabas.

SynchronousQueue<E> - gumagana ang pila ayon sa prinsipyo ng FIFO (first-in-first-out). Hinaharangan ng bawat insert operation ang thread na "Producer" hanggang sa hilahin ng thread na "Consumer" ang elemento mula sa queue at vice versa, maghihintay ang "Consumer" hanggang sa ipasok ng "Producer" ang elemento.

Ang BlockingDeque<E> ay isang interface na naglalarawan ng mga karagdagang pamamaraan para sa isang bidirectional blocking queue. Maaaring ipasok at i-pull out ang data mula sa magkabilang panig ng pila.

Ang LinkedBlockingDeque<E> ay isang bidirectional blocking queue sa mga naka-link na node, na ipinatupad bilang isang simpleng bidirectional na listahan na may isang lock. Ang laki ng pila ay itinakda sa pamamagitan ng constructor at katumbas ng Integer.MAX_VALUE bilang default.

TransferQueue<E> - ang interface ay kawili-wili dahil kapag ang isang elemento ay idinagdag sa queue, posibleng harangan ang pagpasok ng thread ng Producer hanggang sa isa pang Consumer thread na hilahin ang elemento mula sa pila. Maaari ka ring magdagdag ng tseke para sa isang partikular na timeout o magtakda ng tseke para sa nakabinbing Consumer s . Bilang resulta, nakakakuha kami ng mekanismo ng paglilipat ng data na may suporta para sa mga asynchronous at synchronous na mensahe.

Ang LinkedTransferQueue<E> ay isang pagpapatupad ng TransferQueue batay sa Dual Queues na may Slack algorithm. Gumagamit nang husto ng CAS (tingnan sa itaas) at paradahan ng thread kapag walang ginagawa.