1

I have made 2 classes of Producer and Consumer. Producer class creates threads and pushes the items to the blocking queue and consumer class also creates threads which takses the items from the blocking queue.

Now, I was wondering one thing here. Should I define my blocking queue in Producer or in Consumer class? Or it should be a singleton object which is defined in both producer and consumer?

If I define in only one class, then I can access the blocking queue by calling the method of that class from another class. This kind of encapsulates the blocking queue data structure in that class and we are accessing that data structure only by the use of the methods. But, I find calling through method makes it look like, one class is dependent on another class.

While if I create a singleton blocking queue, then, the blocking queue object is shared between 2 classes. But I think its bad practice to share collections between classes making users to know that how to use collections in each class. I am not sure if its really a bad practice.

Please provide your insights on which way is better? Thanks for your help.

hatellla
  • 4,796
  • 8
  • 49
  • 101
  • 5
    How do your create your Consumer and Producer classes? You should be able to create the blocking queue in the same way and inject it in the other two classes. – Nicola Ambrosetti Jun 07 '19 at 06:53
  • Take a look at https://stackoverflow.com/a/2233867/574351 – Nicola Ambrosetti Jun 07 '19 at 07:07
  • A singleton queue, passed to both producer and consumer. Otherwise, how would you want to handle dynamically adding new producers and consumers if they create their own queue? – daniu Jun 07 '19 at 08:10

1 Answers1

2

A blocking queue should be instantiated in the producer class, because the producer actually controls this collection. Consumer would tell the Producer to produce. Instead of the finished product, the Producer returns the blocking collection and sets it to complete once the production is finished. This way the consumer can iterate the blocking collection and knows when to break this iteration. According to this flow, I would instantiate the blocking collection in the Producer scope. But it doesn't really matter. Otherwise the Producer would accept a parameter of a in an external scope created collection. It's turns down to be a question of taste and I think it's cleaner to let the Producer return the collection

I prefer a)

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

over b)

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

Since Java doesn't now references (only copies of references), using my preferred solution a) would give the producer all the freedom to overwrite the BlockingQueue at any time without causing trouble to the Consumer.

Singletons are not good practice and should be avoided whenever possible:

  • Singletons will complicate your tests since you can't mock them.
  • Singletons introduce high coupling due to their static nature.
  • And because of their static nature they are expensive in concurrent scenarios (which might not be relevant in your case), since they would require synchronization or thread-safety
  • Singletons are not controllable in terms of their lifetime. Its lifetime is coupled to the lifetime of the application (or the domain)
BionicCode
  • 1
  • 4
  • 28
  • 44