Dapatkah seseorang menjelaskan secara sederhana apa pola pengacau itu?

Jawaban:

33

The Fowler Pasal penyedia baik primer, dan penjelasan ini:

Pada level kasar, Anda dapat menganggap Disruptor sebagai grafik antrian multicast di mana produsen meletakkan objek di atasnya yang dikirim ke semua konsumen untuk konsumsi paralel melalui antrian hilir yang terpisah. Ketika Anda melihat ke dalam, Anda melihat bahwa jaringan antrian ini benar-benar sebuah struktur data tunggal - penyangga cincin.

Setiap produsen dan konsumen memiliki penghitung urutan untuk menunjukkan slot mana dalam buffer yang sedang dikerjakannya. Setiap produsen / konsumen menulis penghitung urutannya sendiri tetapi dapat membaca penghitung urutan lainnya. Dengan cara ini produsen dapat membaca konter konsumen untuk memastikan slot yang ingin ditulisnya tersedia tanpa kunci di konter. Demikian pula seorang konsumen dapat memastikan hanya memproses pesan setelah konsumen lain selesai dengan itu dengan menonton konter.

masukkan deskripsi gambar di sini

Pendekatan yang lebih konvensional mungkin menggunakan Antrian Produsen dan Antrian Konsumen, masing-masing menggunakan kunci sebagai mekanisme konkurensi. Dalam praktiknya, apa yang terjadi dengan antrian produsen dan konsumen adalah antrian tersebut benar-benar kosong atau sepenuhnya penuh sebagian besar waktu, yang menyebabkan pertikaian kunci dan siklus clock terbuang. Pengganggu meringankan ini, sebagian, dengan memiliki semua produsen dan konsumen menggunakan mekanisme antrian yang sama, berkoordinasi satu sama lain dengan menonton penghitung urutan daripada menggunakan mekanisme penguncian.

Robert Harvey
sumber
9

Dari artikel ini tentang CoralQueue :

Pola pengganggu adalah antrian batching didukung oleh array melingkar (yaitu penyangga cincin) diisi dengan objek transfer pra-dialokasikan yang menggunakan hambatan memori untuk menyinkronkan produsen dan konsumen melalui urutan.

Jadi produsen dan konsumen tidak menginjak satu sama lain di dalam array melingkar dengan memeriksa urutan yang sesuai . Dan untuk mengomunikasikan urutan mereka bolak-balik satu sama lain, mereka menggunakan hambatan memori, bukan kunci. Itulah cara bebas kunci tercepat yang dapat mereka gunakan untuk berkomunikasi.

Untungnya Anda tidak perlu membuka detail internal pola pengganggu untuk menggunakannya. Selain implementasi LMAX ada CoralQueue yang dikembangkan oleh Coral Blocks, yang saya berafiliasi. Beberapa orang merasa lebih mudah untuk memahami konsep dengan membaca kode, jadi di bawah ini adalah contoh sederhana dari satu produsen mengirim pesan ke satu konsumen. Anda juga dapat memeriksa pertanyaan ini untuk contoh demultiplexer (satu produsen ke banyak konsumen).

package com.coralblocks.coralqueue.sample.queue;

import com.coralblocks.coralqueue.AtomicQueue;
import com.coralblocks.coralqueue.Queue;
import com.coralblocks.coralqueue.util.Builder;

public class Basics {

    public static void main(String[] args) {

        final Queue<StringBuilder> queue = new AtomicQueue<StringBuilder>(1024, new Builder<StringBuilder>() {
            @Override
            public StringBuilder newInstance() {
                return new StringBuilder(1024);
            }
        });

        Thread producer = new Thread(new Runnable() {

            private final StringBuilder getStringBuilder() {
                StringBuilder sb;
                while((sb = queue.nextToDispatch()) == null) {
                    // queue can be full if the size of the queue
                    // is small and/or the consumer is too slow

                    // busy spin (you can also use a wait strategy instead)
                }
                return sb;
            }

            @Override
            public void run() {

                StringBuilder sb;

                while(true) { // the main loop of the thread

                    // (...) do whatever you have to do here...

                    // and whenever you want to send a message to
                    // the other thread you can just do:
                    sb = getStringBuilder();
                    sb.setLength(0);
                    sb.append("Hello!");
                    queue.flush();

                    // you can also send in batches to increase throughput:
                    sb = getStringBuilder();
                    sb.setLength(0);
                    sb.append("Hi!");

                    sb = getStringBuilder();
                    sb.setLength(0);
                    sb.append("Hi again!");

                    queue.flush(); // dispatch the two messages above...
                }
            }
        }, "Producer");

        Thread consumer = new Thread(new Runnable() {

            @Override
            public void run() {

                while (true) { // the main loop of the thread

                    // (...) do whatever you have to do here...

                    // and whenever you want to check if the producer
                    // has sent a message you just do:

                    long avail;
                    while((avail = queue.availableToPoll()) == 0) {
                        // queue can be empty!
                        // busy spin (you can also use a wait strategy instead)
                    }

                    for(int i = 0; i < avail; i++) {
                        StringBuilder sb = queue.poll();
                        // (...) do whatever you want to do with the data
                        // just don't call toString() to create garbage...
                        // copy byte-by-byte instead...
                    }
                    queue.donePolling();
                }
            }
        }, "Consumer");

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

Penafian: Saya adalah salah satu pengembang CoralQueue.

rdalmeida
sumber
1
Akan menyenangkan untuk menyatakan afiliasi Anda dengan perangkat lunak yang Anda jelaskan.
Pemburu Rusa