是否有类似于队列的数据结构可以组播到不同的线程?

时间:2014-06-17 16:40:23

标签: java multithreading algorithm data-structures multicast

我想以一种每个线程获取我添加到队列中的所有消息的方式将相同的消息发送到一组线程。它就像一个广播队列。是否有类似的数据结构,最好是在Java?

3 个答案:

答案 0 :(得分:2)

将您的数据存储在静态ConcurrentLinkedQueue中,并让您的线程访问它。

答案 1 :(得分:1)

你可以使用破坏者模式。如果您想要类似于数据结构的内容,可以查看CoralQueue中的Splitter。它允许生产者以每个消费者接收和处理每条消息的方式向多个消费者发送消息。

下面是一个简单的例子:

package com.coralblocks.coralqueue.sample.splitter;

import com.coralblocks.coralqueue.splitter.AtomicSplitter;
import com.coralblocks.coralqueue.splitter.Splitter;
import com.coralblocks.coralqueue.util.Builder;

public class Basics {

    private static final int NUMBER_OF_CONSUMERS = 4;

    public static void main(String[] args) {

        Builder<StringBuilder> builder =  new Builder<StringBuilder>() {
            @Override
            public StringBuilder newInstance() {
                return new StringBuilder(1024);
            }
        };

        final Splitter<StringBuilder> splitter = new AtomicSplitter<StringBuilder>(1024, builder, NUMBER_OF_CONSUMERS);

        Thread producer = new Thread(new Runnable() {

            private final StringBuilder getStringBuilder() {

                StringBuilder sb;

                while((sb = splitter.nextToDispatch()) == null) {
                    // splitter can be full if the size of the splitter
                    // 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!");
                    splitter.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!");

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

        final Thread[] consumers = new Thread[NUMBER_OF_CONSUMERS];

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

            final int index = i;

            consumers[i] = new Thread(new Runnable() {

                @SuppressWarnings("unused")
                @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 = splitter.availableToPoll(index)) == 0) {
                            // splitter can be empty!
                            // busy spin (you can also use a wait strategy instead)
                        }

                        for(int i = 0; i < avail; i++) {

                            StringBuilder sb = splitter.poll(index);

                            // (...) do whatever you want to do with the data
                            // just don't call toString() to create garbage...
                            // copy byte-by-byte instead...
                        }

                        splitter.donePolling(index);
                    }
                }
            }, "Consumer" + index);
        }

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

        producer.start();
    }
}

答案 2 :(得分:0)

您可以创建一个线程来从队列中拾取消息,然后通过在每个线程的本地队列中保存消息将其发送到所有线程。