簡體   English   中英

如何使用干擾模式實現解復用器?

[英]How to implement a demultiplexer using the disruptor pattern?

我希望有一個環形緩沖區隊列,該隊列將以單個生產者方式向多個使用者方式接收對象並將它們分布在線程池中的多個線程之間。 如何使用干擾者模式完成此任務? 任何HelloDemux代碼示例? 謝謝!!!

本文詳細介紹了實現解復用器模式的多路分解器,但我認為線程池意味着您將需要一個與該破壞器模式背道而馳的調度程序。 要實現多路分解,您需要設置固定數量的使用者線程(而不是池),並讓它們從隊列尾部獲取消息。 現在,您可能會問,如果沒有調度員,他們如何做到這一點? 他們只是在隊列尾部忙於旋轉(或使用其他類型的等待策略,這些策略是旋轉,屈服,停車,睡覺等的組合)。 現在,您可能會問,他們如何才能做到彼此之間互不干涉? 然后,您有兩個選擇:您可以使用MODULUS(無鎖)或CAS(輕鎖)。 每個人都有自己的優點和缺點。 MODULUS速度很快,但是如果一個消費者落后,則可能導致通道爭用。 CAS速度不快,但不會引起通道爭用。

package com.coralblocks.coralqueue.sample.demux;

import com.coralblocks.coralqueue.demux.CASAtomicDemux;
import com.coralblocks.coralqueue.demux.Demux;

public class Sample {

    private static final int NUMBER_OF_CONSUMERS = 4;

    public static void main(String[] args) throws InterruptedException {

        final Demux<StringBuilder> queue = new CASAtomicDemux<StringBuilder>(1024, StringBuilder.class, NUMBER_OF_CONSUMERS);

        Thread[] consumers = new Thread[NUMBER_OF_CONSUMERS];

        for(int i = 0; i < consumers.length; i++) {

            final int index = i;

            consumers[i] = new Thread() {

                @Override
                public void run() {

                    boolean running = true;

                    while(running) {
                        long avail;
                        while((avail = queue.availableToPoll(index)) == 0); // busy spin
                        for(int i = 0; i < avail; i++) {
                            StringBuilder sb = queue.poll(index);

                            if (sb == null) break; // mandatory for demuxes!

                            if (sb.length() == 0) {
                                running = false;
                                break; // exit immediately...
                            } else {
                                System.out.println(sb.toString());
                            }
                        }
                        queue.donePolling(index);
                    }
                }
            };

            consumers[i].start();
        }

        StringBuilder sb;

        for(int i = 0; i < 10; i++) {
            while((sb = queue.nextToDispatch()) == null); // busy spin
            sb.setLength(0);
            sb.append("message ").append(i);
            queue.flush();
        }

        // send a message to stop consumers...
        for(int i = 0; i < NUMBER_OF_CONSUMERS; i++) {
            // because the consumer exit immediately on this message, each
            // consumer will get one of these messages and exit...
            while((sb = queue.nextToDispatch()) == null); // busy spin
            sb.setLength(0);
        }
        queue.flush(); // sent batch

        for(int i = 0; i < consumers.length; i++) consumers[i].join();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM