Java使用者线程等待所有生产者线程完成

Java使用者线程等待所有生产者线程完成,java,multithreading,producer-consumer,Java,Multithreading,Producer Consumer,我有一个生产者-消费者模式的多线程任务。可能有许多生产者和一个消费者。我使用ArrayBlockingQueue作为共享资源 生产者类中的run()方法: public void run() { for (Order order : orderList) { try { queue.put(order); } catch (InterruptedException e) {

我有一个生产者-消费者模式的多线程任务。可能有许多生产者和一个消费者。我使用ArrayBlockingQueue作为共享资源

生产者类中的run()方法:

public void run() {
         for (Order order : orderList) {
             try {
                 queue.put(order);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         log.info("{} has placed all orders", Thread.currentThread().getName());
     }
     public void run() {
         while (!queue.isEmpty()) {
             try {
                 Order order = queue.take();
                 checkOrder(order);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         log.info("All orders has been checked");
     }
// creating N producers
         for (int i = 0; i < PRODUCERS_NUM; i++) {
             Producer producer = new Producer(orderQueue, orderList);
             new Thread(producer , "Producer " + i).start();
         }
 
         Thread consumerThread = new Thread(new Consumer(orderQueue, limitList), "Consumer");
         consumerThread.start();
         consumerThread.join();

**Printing results **
消费者类中的run()方法:

public void run() {
         for (Order order : orderList) {
             try {
                 queue.put(order);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         log.info("{} has placed all orders", Thread.currentThread().getName());
     }
     public void run() {
         while (!queue.isEmpty()) {
             try {
                 Order order = queue.take();
                 checkOrder(order);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         log.info("All orders has been checked");
     }
// creating N producers
         for (int i = 0; i < PRODUCERS_NUM; i++) {
             Producer producer = new Producer(orderQueue, orderList);
             new Thread(producer , "Producer " + i).start();
         }
 
         Thread consumerThread = new Thread(new Consumer(orderQueue, limitList), "Consumer");
         consumerThread.start();
         consumerThread.join();

**Printing results **
main()方法:

public void run() {
         for (Order order : orderList) {
             try {
                 queue.put(order);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         log.info("{} has placed all orders", Thread.currentThread().getName());
     }
     public void run() {
         while (!queue.isEmpty()) {
             try {
                 Order order = queue.take();
                 checkOrder(order);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         log.info("All orders has been checked");
     }
// creating N producers
         for (int i = 0; i < PRODUCERS_NUM; i++) {
             Producer producer = new Producer(orderQueue, orderList);
             new Thread(producer , "Producer " + i).start();
         }
 
         Thread consumerThread = new Thread(new Consumer(orderQueue, limitList), "Consumer");
         consumerThread.start();
         consumerThread.join();

**Printing results **
//创建N个生产者
for(int i=0;i
现在我有了当队列为空时的消费者结束条件。但可能会有一段时间队列变空,但一些生产者线程仍在工作。所以我只需要在所有生产者线程都完成之后才完成消费者线程(但它们的数量事先不知道)


什么是正确的编码方式?

由于您有固定数量的生产者,我建议在开始时设置一个计数器,以生产者的数量为准。每个生产者在计数器完成时递减计数器,消费者仅在计数器达到零时终止。对于计数器,您可能希望使用。

为什么不使用CountDownLatch?我尝试了这个方法,但对我来说似乎不是很干净,因为我需要向生产者和消费者提供额外的参数(计数器)。因此,我想寻找更好的解决方案。@codeflush.dev我认为倒计时锁存器不是一个解决方案,因为消费者希望在计数器大于0时取得进展。可以将CountDownLatch与getCount一起使用,而不是Wait,但这与原子整数是一样的。@VitalyKolesnikov无论您做什么,都需要有一种机制,让生产者与消费者沟通它尚未完成。这可能是已共享状态(队列)的一部分,也可能是新的。将关注点分开并将其作为单独的东西似乎更合理。我想您可以使用此计数器扩展队列,以创建CountingQueue或类似的队列,其中制作人在开始时计数,在结束时计数。对不起,我应该指出,您需要注意消费者在生产者之前开始的竞争条件,例如,您可能希望在创建生产者时在主线程中进行计数,而不是在生产者线程中进行计数。