Завершение в многопоточном Java-редакторе Producer Consumer
Я делаю некоторые упражнения с функциями многопоточности и параллелизма Java. У меня 1 производитель и 4 потребителя. Теперь мои вопросы: есть ли какой-нибудь более умный способ остановить потребителей, когда я уверен, что производитель закончил производить в BlockingQueue? На данный момент я использую целое число -1 в очереди, но выглядит очень элементарно!! Спасибо
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 ответ
Вы можете использовать таблетку с ядом, однако более надежный способ использовать такую таблетку с ядом - это не удалять ее из очереди (или откладывать обратно, если это так). Производителю не нужно знать, сколько у вас потребителей. иметь.
Кстати, я бы не использовал явный бокс, так как он более многословный и медленный.
Вместо
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);