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

时间:2019-06-07 06:45:32

标签: java design-patterns producer-consumer blockingqueue

我把生产者和消费者分为两类。生产者类创建线程并将项目推送到阻塞队列,而消费者类也创建线程以从阻塞队列中获取项目。

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

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

虽然我创建了一个单例阻塞队列,但是阻塞队列对象在2个类之间共享。但是我认为在类之间共享集合是一种不好的做法,使用户知道如何在每个类中使用集合。我不确定这是否真的是不好的做法。

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

1 个答案:

答案 0 :(得分:1)

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

我更喜欢a)

BlockingQueue result = producer.produce();
while (!result.isCompleted) {}

b)

BlockingQueue result = new BlockingQueue();
producer.produce(result);
while (!result.isCompleted) {}

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

单挑不是好习惯,应尽可能避免:

  • Singletons将使您的测试复杂化,因为您无法模拟它们。
  • 单子由于其静态特性而引入高耦合。
  • 由于它们的静态性质,它们在并发场景中很昂贵(这可能与您的情况无关),因为它们需要同步或线程安全性
  • 单子的生命周期不可控。它的生存期与应用程序(或域)的生存期有关