Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 阻塞队列应该在生产者类还是消费者类中定义?_Java_Design Patterns_Producer Consumer_Blockingqueue - Fatal编程技术网

Java 阻塞队列应该在生产者类还是消费者类中定义?

Java 阻塞队列应该在生产者类还是消费者类中定义?,java,design-patterns,producer-consumer,blockingqueue,Java,Design Patterns,Producer Consumer,Blockingqueue,我做了两个类别的生产者和消费者。生产者类创建线程并将项目推送到阻塞队列,消费者类还创建线程,从阻塞队列中获取项目 现在,我想知道一件事。我应该在Producer类还是Consumer类中定义阻塞队列?或者它应该是生产者和消费者都定义的单例对象 如果我只在一个类中定义,那么我可以通过从另一个类调用该类的方法来访问阻塞队列。这种方法将阻塞队列数据结构封装在该类中,我们仅通过使用这些方法访问该数据结构。但是,我发现通过方法调用使它看起来像是一个类依赖于另一个类 如果我创建一个单例阻塞队列,那么阻塞队列

我做了两个类别的生产者和消费者。生产者类创建线程并将项目推送到阻塞队列,消费者类还创建线程,从阻塞队列中获取项目

现在,我想知道一件事。我应该在Producer类还是Consumer类中定义阻塞队列?或者它应该是生产者和消费者都定义的单例对象

如果我只在一个类中定义,那么我可以通过从另一个类调用该类的方法来访问阻塞队列。这种方法将阻塞队列数据结构封装在该类中,我们仅通过使用这些方法访问该数据结构。但是,我发现通过方法调用使它看起来像是一个类依赖于另一个类

如果我创建一个单例阻塞队列,那么阻塞队列对象将在两个类之间共享。但我认为在类之间共享集合是一种不好的做法,这会让用户知道如何在每个类中使用集合。我不确定这是否真的是一个坏习惯


请提供您对哪种方式更好的见解?感谢您的帮助。

应该在producer类中实例化阻塞队列,因为producer实际上控制此集合。消费者会告诉生产者生产。生产者返回阻塞集合而不是成品,并在生产完成后将其设置为完成。这样,使用者可以迭代阻塞集合,并知道何时中断此迭代。根据这个流程,我将在Producer范围内实例化阻塞集合。但这并不重要。否则,生产者将接受外部作用域创建集合中的参数。这是一个口味的问题,我认为让制作人归还收藏品更干净

我更喜欢a)

超过b)

由于Java现在不引用(仅引用的副本),因此使用我首选的解决方案a)将使生产者可以随时覆盖
BlockingQueue
,而不会给消费者带来麻烦

单身不是好的做法,应尽可能避免:

  • 因为你不能模仿,所以单身会使你的测试复杂化
  • 由于其静态特性,单件引入了高耦合
  • 而且由于它们的静态特性,在并发场景中它们的成本很高(这在您的案例中可能不相关),因为它们需要同步或线程安全
  • 就其生命周期而言,单身是不可控的。其生存期与应用程序(或域)的生存期耦合

您如何创建您的消费者和生产者类别?您应该能够以相同的方式创建阻塞队列,并将其注入其他两个类中。否则,如果生产者和消费者创建自己的队列,您希望如何处理动态添加新生产者和消费者的问题?
BlockingQueue result = producer.produce();
while (!result.isCompleted) {}
BlockingQueue result = new BlockingQueue();
producer.produce(result);
while (!result.isCompleted) {}