Как стать автором
Обновить

Комментарии 7

Работа генератора кораблей не должна зависеть от работы причалов и наоборот

Оно таки может привести к проблеме fast producer — slow consumer.
Генератор не должен генерить новые корабли если причалы ещё загружают, а "тунель" полон.


Есть разные стратегии обработки таких сценариев:
1) Pull. Туннель будет буфером на 5 кораблей, когда буфер неполон, он сам просит нагенерить ему ещё кораблей, а в это время причалы грузят нонстоп, все довольны.
Т.е. генератор выступает тут итератором, у которого есть метод — CreateNext()


2) Drop. Если генератор ну очень хочет генерить корабли постоянно, а тунель не справляется, то можно дропать все корабли сверх лимита. Под словом дропать можно понимать разное: именно что дропать и забывать навсегда, или же поднимать новый "тунель" и засылать в него.

Оно таки может привести к проблеме fast producer — slow consumer.
Генератор не должен генерить новые корабли если причалы ещё загружают, а «тунель» полон.

Генератор в данной реализаций так и реализован, он не генерирует новые кораблики пока место в «туннели» не освободиться. Он засыпает.
2) Drop. Если генератор ну очень хочет генерить корабли постоянно, а тунель не справляется, то можно дропать все корабли сверх лимита. Под словом дропать можно понимать разное: именно что дропать и забывать навсегда, или же поднимать новый «тунель» и засылать в него.

Я думаю такой подход не очень эффективен, если поток будет постоянно находиться в состояний RUNNABLE )
Генератор в данной реализаций так и реализован, он не генерирует новые кораблики пока место в «туннели» не освободиться. Он засыпает.

Тогда ваше требование о независимости генератора от туннеля не выполняется.
И вместо поллинга со стороны генератора лучше сделать pull данных со стороны туннеля.


Я вообще сам дотнетчик, но знаю что в Scala есть Akka Streams, хз юзабельно оно или нет из Java


Полезное чтиво:
https://doc.akka.io/docs/akka/2.5/stream/stream-quickstart.html#back-pressure-in-action


A typical problem applications (not using Akka Streams) like this often face is that they are unable to process the incoming data fast enough, either temporarily or by design, and will start buffering incoming data until there’s no more space to buffer, resulting in either OutOfMemoryError s or other severe degradations of service responsiveness.
Вместо написания класса Tunnel можно было использовать любую BlockingQueue из пакета java.util.concurrent (например ArrayBlockingQueue), которая выполняет почти те же задачи.
Из статьи которая выше:
Справедливости ради, стоит отметить, что никто не принуждал делать это низкоуровневыми инструментами такими как wait() и notify(), когда можно без великих хитростей использовать ArrayBlockingQueue, Semophore и в целом мощный API(java.util.concurrent).

Как раз таки ArrayBlockingQueue я использовал в другой моей реализаций.
Для периодичности исполнения задач (как например в ShipGenerator) лучше использовать ScheduledExecutorService с задержкой вызова в 1 секунду и избавиться от Thread.sleep(1000). Так и код чище и работать будет более грамотно.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории