2014-06-17 5 views
1

각 스레드가 내가 큐에 추가하는 모든 메시지를받는 방식으로 같은 메시지를 스레드 집합에 보내고 싶습니다. 방송 대기열과 같습니다. Java와 같은 데이터 구조가 있습니까?다른 스레드에 멀티 캐스트를 수행 할 수있는 큐와 유사한 데이터 구조가 있습니까?

+0

실행중인 스레드는 어디입니까? – Typo

+1

http://stackoverflow.com/questions/8891284/java-concurrent-queue-for-broadcast를 보았습니까? https://github.com/android/platform_frameworks_base/blob/master/services/java/com/android/server/am/BroadcastQueue.java를 적용 할 수 있습니까? –

답변

2

정적 데이터 ConcurrentLinkedQueue에 데이터를 저장하고 스레드에 액세스하도록하십시오.

+0

이것은 작동하지 않습니다. 스레드가 메시지를 받으면 다른 스레드는 동일한 메시지를받지 못합니다. – JohnPristine

+0

@JohnPristine이 폴링하지 않고, 그냥 peek : – Mifmif

+0

if (queue.peek()! = null) grab (queue.poll()); – Kyte

1

그런 경우 장애 패턴을 사용할 수 있습니다. 데이터 구조와 비슷한 것을 원한다면 SplitterCoralQueue에서 확인할 수 있습니다. 그것은 생산자가 각 소비자가 각 메시지를 받아서 처리하는 방식으로 여러 소비자에게 메시지를 보낼 수있게합니다.

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(); 
    } 
} 
0

당신은 픽업 큐에서 메시지를 스레드를 만들 수 있습니다 다음 각 스레드 로컬 큐에 메시지를 저장하여 모든 스레드로 보내 :

다음은 간단한 예입니다.