2017-09-03 2 views
0

하나의 제작자와 여러 소비자에 대해 코드를 실행하고 있습니다. 소비자 스레드의 실행 우선 순위를 지정하려고합니다. ie consThread1, consThread2, consThread3이있는 경우. 내 질문에 consThread1 및 consThread2소비자 스레드 실행 순서를 유지하는 방법

Producer.java

import java.util.concurrent.BlockingQueue; 
import org.json.simple.JSONObject; 

public class Producer implements Runnable { 
    private final BlockingQueue<Message> sharedQueue; 

    @SuppressWarnings("unchecked") 
    public Producer(BlockingQueue<Message> sharedQueue){ 
     this.sharedQueue=sharedQueue; 
    } 

    @Override 
    public void run() { 
     try{ 
      for(int i=0;i<4;i++) { 
       Message msg=new Message(""+i); 
       System.out.println("Producer Produced: " +msg.getMessage()); 
       sharedQueue.put(msg); 
       Thread.sleep(400); 
      } 
      sharedQueue.put(new Message("exit")); // end of producing 
      System.out.println("-------Producer STOPPED------"); 
     } 
     catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Consumer.java 전에

import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.TimeUnit; 
import org.json.simple.JSONObject; 

public class Consumer implements Runnable{ 

    private final BlockingQueue<Message> sharedQueue; 
    private String threadId; 

    public Consumer(BlockingQueue<Message> sharedQueue) {   
     this.sharedQueue=sharedQueue;   
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    public void run() { 
     threadId = "Consumer-" + Thread.currentThread().getName(); 
     try { 
      Message msg; 
      while (true){ 
       msg=sharedQueue.poll(5,TimeUnit.SECONDS); 
       if(msg.getMessage()=="exit" || msg.getMessage()==null){ 
        sharedQueue.put(new Message("exit")); 
        break; 
       } 
       System.out.println(threadId + ": Consuming Message " + msg.getMessage()); 
       Thread.sleep(1000); 
      } 
      System.out.println(threadId + " STOPPED Consuming "); 
     } 
     catch (InterruptedException ie) { 
      ie.printStackTrace(); 
     } 
    } 
} 

테스트 프로그램 ProducerConsumer.java

import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.LinkedBlockingQueue; 
import org.json.simple.JSONObject; 

public class ProducerConsumer { 

    public static void main(String[] args) throws InterruptedException { 
     BlockingQueue<Message> sharedQueue = new LinkedBlockingQueue<>(10); 

     //Creating Producer and Consumer Thread 
     Thread prodThread = new Thread(new Producer(sharedQueue)); 
     Thread consThread1 = new Thread(new Consumer(sharedQueue)); 
     Thread consThread2 = new Thread(new Consumer(sharedQueue)); 
     Thread consThread3 = new Thread(new Consumer(sharedQueue)); 
     //Starting producer and Consumer thread 
     System.out.println("Producer and consumer threads started \n\n\n---------------------------------------"); 

     prodThread.start(); 
     consThread1.start(); 
     consThread2.start(); 
     consThread1.join(); 
     consThread2.join(); 
     consThread3.start(); 
    } 
} 
+1

왜 그렇게 원하십니까? – Kayaman

+7

그래서 3 개의 항목을 동시에 소비 할 수 있도록 3 개의 소비자 스레드를 생성하고 있지만 실제로는 순차적으로 소비하지 않고 동시에 소비하기를 원하십니까? 왜 3 개의 스레드를 시작해야합니까? 단일 소비자 스레드 만 사용하면 소비가 순차적으로 발생합니다. –

+0

http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setPriority(int)하지만 JB가 지적한 바와 같이 왜 세 개의 스레드를 사용해야합니까? – nullpointer

답변

-1

만약을 소비 consThread3을 제한하는 방법이다 당신은 하나씩 실행하고 싶습니다. 왜 다중 쓰레드를 사용합니까? 하나의 스레드로 리펙토링해야합니다.

그러나 리팩토링을 건너 뛰려면 소모하는 스레드를 고정 된 스레드 풀에 넣으면됩니다. 스레드 풀에서 최대 활성 스레드 수를 설정할 수 있으므로 최대 값을 1로 설정할 수 있고 스레드 풀이 스레드를 하나씩 실행합니다.

또 다른 대안은 장벽 조치가 세 번째 스레드 (다른 스레드 뒤에 호출 됨) 인 순환 장벽을 만드는 것입니다. 순환 장벽을 통해 처음 두 스레드를 실행할 수 있습니다. 장벽은 마무리 스레드를 계산할 수 있으며 임계 값에 도달하면 세 번째 스레드를 실행합니다. 이것은 이벤트가 소비 될 때까지 기다리는 3 번째 소비자 스레드를 원한다는 목표를 충족시켜야합니다.