#java #multithreading #concurrency
Вопрос:
Возможно, это стандартная проблема с многопоточностью, и у нее есть название.
В очереди есть список элементов с каждым элементом : {"resource" : "r1", "action" : "create"}
. Теперь постановка задачи состоит в том, чтобы считывать данные из этой очереди и обрабатывать операции многопоточным способом. Но операция в отношении конкретного ресурса должна быть в порядке.
Например, ввод образца :
[{"resource" : "r1", "action" : "create"}, {"resource" : "r2", "action" : "create"}, {"resource" : "r1", "action" : "update"}]
.
Ожидается, что r2 может быть обработан до r1, но операция создания r1 должна быть выполнена до операции обновления.
1 решение, о котором я подумал и отказался, состояло в том, чтобы иметь выделенный поток для каждого ресурса, но поскольку количество потоков ограничено, а ввод данных велик, это не сработает.
Есть какие-нибудь предложения?
Комментарии:
1. Используйте Кафку, чтобы вы могли выполнять задачи только после завершения предыдущей задачи.
2. Стандартным способом было бы определить общую блокировку или семафор для каждого ресурса. Когда задача должна быть взята из очереди, необходимо получить блокировку/семафор. Если приобретение не удается, пропустите задачу и выполните следующую. Когда задача завершена, блокировка/семафор должны быть сняты.
Ответ №1:
Да, вы правы. Имя-PriorityBlockingQueue, которое является потокобезопасным и обеспечивает гибкость для объявления пользовательского компаратора объектов в очереди в виде аргумента конструктора.
Комментарии:
1. PriorityBlockingQueue можно использовать для обеспечения запуска создания до обновления на том же ресурсе, но при использовании потоков >1 нет гарантии, что операция создания будет фактически завершена до запуска обновления.
Ответ №2:
Вы можете реализовать архитектуру драйвера/рабочего здесь.
Там будет несколько работников, прослушивающих их соответствующие очереди. Количество работников будет зависеть от объема мероприятий.
Ответственность мастера будет заключаться в чтении из основной очереди и сопоставлении поля ресурсов с конкретной рабочей очередью. Таким образом, это будет означать, что все события/элементы ресурса будут отправляться только в определенную очередь. Это сопоставление ресурса конкретному работнику может происходить с помощью какой-либо статической карты или хэширования ресурса в идентификатор работника.
Это очень похоже на концепцию разделения, когда мы используем ключ раздела, чтобы гарантировать порядок в конкретном разделе.