据GeeksforGeeks-ProducerConsumerProblem说,我对第二次练习感到困惑:
尝试让您的程序生成一个项目,然后消费者在消费者生产任何其他项目之前消费它。
怎么解决?我认为在制作人生成一个项目后,我们可以在生产者将一个项目添加到列表后记录大小。而while(list.size()== recordSize)wait();这是对的吗?感谢您的时间。
您可以使用标志变量,并且每次要生成项目时都需要验证此标志是否为false。 (如果您已经生成了一个项目,那么该标志为True,因此在您知道消费者已经处理它之前您不能生成另一个项目,您应该使用synchronized来保护此标志的值)。现在,如果标志为假,添加一个项目然后wait()
或者只是wait()
供消费者使用它,然后在消费者代码中使用notify()
继续。你还应该在消费者代码中使用wait()
等到生产者生产一个项目,然后当你完成使用notify()
和wait()
等待新项目。
生产者可以留下一个Future供消费者填充。然后生产者调用Future
的get()
方法,这将导致生产者线程停止直到消费者完成。这种解决方案本质上是现代的,因为它是在野外完成的方式。使用CountDownLatch也可以做到这一点。锁存器和未来之间的区别在于,当生产者需要生成Future
对象的持有者所需的对象时,使用Future。而CountDownLatch
主要用于同步多个线程。
虽然在这个例子中使Future
或CountDOwnLatch
工作需要对问题进行一些改变,例如LinkedList
将不仅仅要传递Integer
。一个更简单的解决方案是用LinkedList
换掉SynchronousQueue。 SynchronousQueue
中包含零元素,因此当一个项目插入队列时,队列将阻塞,直到消费者到达并获取该项目。进一步尝试将一个物体加入到put
中将会阻塞物品被消耗。生产者可以尝试在生产者完成前一个项目之前将enxt项目放入队列,但是它将再次等待消费者出现并获得它。
用SynchronousQueue
替换while (list.size() == capacity)
。通过这样做,while (list.size() == 1)
将只生产1项并等待producer
消耗它。