0

멀티 스레드 및 Java 동시성 기능에 대한 연습을하고 있습니다. 1 명의 생산자와 4 명의 소비자가 있습니다. 이제 내 질문은 : 생산자가 BlockingQueue에서 생산을 완료했다고 확신 할 때 소비자를 중단시키는 더 현명한 방법이 있습니까? 지금은 대기열에 -1 정수를 사용하고 있지만 매우 기초적으로 보입니다! 는생산자의 종료 Consumer multithreading Java

public class Exercise { 

static class Producer implements Runnable { 
    int counter=0; 
    private BlockingQueue<Integer> queue; 
    Producer(BlockingQueue<Integer> q) { 
     queue = q; 
    } 
    public void run() { 
     try { 
      while (counter<100000000) { 
       queue.put(produce()); 
      } 
      queue.put(new Integer(-1)); 
      queue.put(new Integer(-1)); 
      queue.put(new Integer(-1)); 
      queue.put(new Integer(-1)); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    Integer produce() { 
     counter++; 
     return new Integer(counter); 

    } 
} 

static class Consumer implements Runnable { 
    private final BlockingQueue<Integer> queue; 
    private String name; 
    private long sum; 

    Consumer(BlockingQueue<Integer> q, String name) { 
     queue = q; 
     this.name=name; 
     sum=0; 
    } 

    public void run() { 
     try { 
      int x=0; 
      while (x>=0) { 
       x=queue.take(); 
       if(x!=-1)sum+=x; 
      } 
      System.out.println(sum+" of "+ name); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 



public static void main(String[] args) { 

    ExecutorService exec = Executors.newFixedThreadPool(6); 
    BlockingQueue<Integer> q =new LinkedTransferQueue<Integer>(); 
    Producer p=new Producer(q);  
    Consumer c1 = new Consumer(q,"consumer1"); 
    Consumer c2 = new Consumer(q,"consumer2"); 
    Consumer c3 = new Consumer(q,"consumer3"); 
    Consumer c4 = new Consumer(q,"consumer4"); 
    exec.submit(p); 
    exec.submit(c1); 
    exec.execute(c2); 
    exec.submit(c3); 
    exec.execute(c4); 
    exec.shutdown(); 
} 

}

답변

1

당신은 대기열에서 제거하지 않는 (또는 당신이 경우에 다시 넣어 같은 독약이다 사용하지만보다 강력한 방법을 독약을 사용할 수 있습니다 감사) 제작자에게이 방법은 당신이 얼마나 많은 소비자를 가지고 있는지 알 필요가 없습니다.

BTW 좀 더 자세하고 느린 것처럼 명시적인 복싱을 사용하지 않는 것이 좋습니다.

대신

queue.put(new Integer(-1)); 

의 당신은

queue.put(-1); 

또는 더 나은을 쓸 수

static final int POISON_PILL = -1; 

// on the producer 
queue.put(POISON_PILL); 

// on the consumer 
while ((x = queue.take()) != POISON_PILL) { 
    sum += x; 
queue.put(POISON_PILL);