Должна ли блокирующая очередь быть определена в классе производителя или классе потребителя? - PullRequest
0 голосов
/ 07 июня 2019

Я сделал 2 класса Продюсер и Потребитель.Класс Producer создает потоки и помещает элементы в очередь блокировки, а потребительский класс также создает потоки, которые отбирают элементы из очереди блокировки.

Теперь мне было интересно вот что.Должен ли я определить свою очередь блокировки в Producer или в классе Consumer?Или это должен быть одноэлементный объект, который определяется как производителем, так и потребителем?

Если я определю только один класс, то я могу получить доступ к очереди блокировки, вызвав метод этого класса из другого класса.Этот вид инкапсулирует структуру данных очереди блокировки в этом классе, и мы получаем доступ к этой структуре данных только с помощью методов.Но я считаю, что при вызове метода через него один класс зависит от другого.

Хотя, если я создаю одиночную очередь блокировки, объект очереди блокировки будет разделен между двумя классами.Но я считаю плохой практикой делиться коллекциями между классами, чтобы пользователи знали, как использовать коллекции в каждом классе.Я не уверен, действительно ли это плохая практика.

Пожалуйста, укажите, какой путь лучше?Спасибо за вашу помощь.

1 Ответ

1 голос
/ 07 июня 2019

Очередь блокировки должна создаваться в классе производителя, потому что производитель фактически контролирует эту коллекцию.Потребитель скажет производителю.Вместо готового продукта Производитель возвращает блокирующий набор и устанавливает его для завершения после завершения производства.Таким образом, потребитель может итерировать коллекцию блокировок и знать, когда прервать эту итерацию.В соответствии с этим потоком я бы создал экземпляр блокирующей коллекции в области действия Producer.Но это не имеет значения.В противном случае Производитель будет принимать параметр a во внешней коллекции, созданной областью действия.Это вопрос вкуса, и я думаю, что чище позволить Продюсеру вернуть коллекцию

Я предпочитаю а)

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

более б)

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

Поскольку Java теперь не ссылается (только копии ссылок), использование моего предпочтительного решения а) даст производителю полную свободу перезаписывать BlockingQueue в любое время, не создавая проблем потребителю.

Синглеты не являются хорошей практикой, и их следует избегать всякий раз, когда это возможно:

  • Синглеты усложняют ваши тесты, поскольку вы не можете их высмеивать.
  • Синглтоны вводят высокую связь из-за своей статической природы.
  • И из-за своей статической природы они дороги в параллельных сценариях (которые могут быть неактуальны в вашем случае), поскольку они требуют синхронизации или безопасности потоков
  • Синглтоны не контролируются всроки их жизни.Его время жизни связано с временем жизни приложения (или домена)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...