Поток безопасно цикл через ConcurrentHashMap без блокировки - PullRequest
0 голосов
/ 16 января 2019

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

Я разрабатываю функцию журнала расписаний, которая периодически регистрирует сообщения, чтобы предотвратить сброс одинаковых сообщений в журнале.

Таким образом, класс журнала содержит ConcurrentHashMap, один поток обновляет его (вставляет новый ключ или обновляет существующее значение), другой поток периодически перебирает карту для регистрации всех сообщений.

Мое беспокойство связано с тем, что необходимо вести журнал при циклическом прохождении карты, что может занять некоторое время, блокирует ли он поток, пытающийся обновить карту? Любая блокировка недопустима, поскольку ядро ​​нашего приложения является однопоточным.

И есть ли какая-либо другая структура данных, кроме ConcurrentHashMap, которую я могу использовать, чтобы уменьшить объем памяти?

Существует ли потокобезопасный способ итерации карты без блокировки в случае только для чтения? Даже итерированные данные могут быть устаревшими, все еще приемлемы.

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Могут быть и другие структуры, которые позволят вам уменьшить объем памяти, уменьшить задержки и, возможно, предложить более равномерный и согласованный профиль производительности.

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

Одной из возможных структур данных для этого является ConcurrentLinked Queue .У меня очень мало опыта работы с Java, поэтому я не уверен, насколько профиль производительности этого отличается от одновременного hashmap;но это очень распространенная модель в распределенных системах и в golang.

0 голосов
/ 16 января 2019

Согласно документации Java API , это говорит, что:

[...], хотя все операции являются поточно-ориентированными, операции поиска не влекут за собой блокировку [...]

Кроме того, документация метода entrySet () сообщает нам, что:

[возвращенный] набор поддерживается картой, поэтому изменения в карте отражаются в наборе и наоборот.

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

...