Antrian Non-Blocking

Utas-aman lan sing paling penting non-blocking implementasine Antrian ing simpul disambung.

ConcurrentLinkedQueue<E> - nggunakake algoritma tanpa ngenteni sing diadaptasi kanggo nggarap tukang sampah. Algoritma iki cukup efisien lan cepet banget, amarga dibangun ing CAS. Ukuran () carabisa mbukak kanggo dangu, supaya iku paling apik ora kanggo narik kabeh wektu.

ConcurrentLinkedDeque<E> - Deque iku singkatan saka Double ended queue. Iki tegese data bisa ditambahake lan ditarik saka loro-lorone. Mulane, kelas ndhukung loro mode operasi: FIFO (First In First Out) lan LIFO (Last In First Out).

Ing laku, ConcurrentLinkedDeque kudu digunakake yen LIFO pancen perlu, amarga amarga bidirectionality saka kelenjar, kelas iki ilang setengah ing kinerja dibandhingake 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();
           }
       }
   }
}

Pamblokiran Antrian

Antarmuka BlockingQueue<E> - yen ana akeh data, ConcurrentLinkedQueue ora cukup.

Yen benang gagal nindakake tugase, sampeyan bisa entuk OutOfMemmoryException kanthi gampang . Lan supaya kasus kaya mengkono ora njedhul, kita duwe BlockingQueue kanggo karya karo ngarsane macem-macem cara kanggo ngisi lan nggarap antrian lan kunci kondisional.

BlockingQueue ora ngenali unsur null lan mbuwang NullPointerException nalika nyoba kanggo nambah utawa njaluk unsur kuwi. Cara polling ngasilake unsur null yen ora ana unsur sing diselehake ing antrian sajrone wektu entek.

BlockingQueue<E> Implementasi

Ayo ndeleng luwih cedhak saben implementasi BlockingQueue :

ArrayBlockingQueue<E> minangka kelas antrian pamblokiran sing dibangun ing buffer ring klasik. Ing kene kita duwe kesempatan kanggo ngatur "kejujuran" kunci. Yen adil = palsu (standar), banjur urutan thread ora dijamin.

DelayQueue<E ngluwihi Tundha> punika kelas sing ngijini sampeyan kanggo narik unsur saka antrian mung sawise wektu tundha tartamtu, ditetepake ing saben unsur liwat cara getDelay antarmuka Tertunda .

LinkedBlockingQueue<E> minangka antrian pamblokiran ing simpul sing disambung, dileksanakake ing algoritma "loro antrian kunci": kunci pisanan kanggo nambah, sing kapindho kanggo narik unsur saka antrian. Amarga kunci, dibandhingake ArrayBlockingQueue , kelas iki nduweni kinerja dhuwur, nanging mbutuhake memori luwih. Ukuran antrian disetel liwat konstruktor lan padha karo Integer.MAX_VALUE minangka standar.

PriorityBlockingQueue<E> iku pambungkus multi-threaded liwat PriorityQueue . Comparator tanggung jawab kanggo logika sing unsur bakal ditambahake. Unsur paling cilik metu pisanan.

SynchronousQueue<E> - antrian dianggo miturut prinsip FIFO (first-in-first-out). Saben operasi insert mblokir thread "Produser" nganti thread "Konsumen" narik unsur saka antrian lan kosok balene, "Konsumen" bakal ngenteni nganti "Produser" nglebokake unsur.

BlockingDeque<E> minangka antarmuka sing njlèntrèhaké cara tambahan kanggo antrian pamblokiran bidirectional. Data bisa dilebokake lan ditarik metu saka loro-lorone antrian.

LinkedBlockingDeque<E> minangka antrian pamblokiran bidirectional ing simpul sing disambung, dileksanakake minangka dhaptar bidirectional prasaja kanthi siji kunci. Ukuran antrian disetel liwat konstruktor lan padha karo Integer.MAX_VALUE minangka standar.

TransferQueue<E> - antarmuka sing menarik nalika unsur ditambahake menyang antrian, iku bisa kanggo mblokir nglebokake Utas Produser nganti Utas Consumer liyane narik unsur saka antrian. Sampeyan uga bisa nambah mriksa kanggo wektu entek tartamtu utawa nyetel mriksa kanggo Konsumen sing ditundha . Akibaté, kita entuk mekanisme transfer data kanthi dhukungan kanggo pesen sing ora sinkron lan sinkron.

LinkedTransferQueue<E> minangka implementasi TransferQueue adhedhasar Antrian Ganda kanthi algoritma Slack. Ndadekake heavy nggunakake CAS (ndeleng ndhuwur) lan thread parking nalika meneng.