2016-04-21 4 views
1

У меня есть событие, которое мне нужно отправить всем активным соединениям, и я использую ChannelGroup.write() для этого процесса. По мере того, как событие проходит через обработчики исходящих сообщений, поле в событии модифицируется с уникальным значением для этого соединения перед созданием окончательного ByteBuf. Проблема заключается в том, что ChannelGroup.write() отправляет одно и то же событие каждому соединению, и исходящие обработчики каждого соединения модифицируют это поле. Это создает условие гонки, и получатели моего события могут прочитать событие с неправильным значением в этом поле.Запись события в Netty ChannelGroup создает условие гонки

Я не уверен, как решить эту проблему. Я мог бы написать свой собственный метод WriteGroup Channel(), который будет ждать, пока событие будет отправлено до отправки следующего. Или я мог бы создать несколько копий моего события и отправить их каждому соединению. В любом случае, я пишу какой-то пользовательский код.

Любая помощь была бы принята с благодарностью.

ответ

1

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

При таком подходе:

Вы не должны написать свой собственный ChannelGroup.write() реализации. Вы можете просто скопировать объект события и изменить значение в своем обработчике, прежде чем передавать его, но предпочитаете создавать новое непреложное событие.

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

+0

Благодарим за быстрый ответ. Как и во многих ситуациях, таких как у меня есть унаследованное приложение, где я заменяю сетевую часть Netty и создаю неизменяемый класс, ставит меня на территорию, на которую я не хочу идти. Я буду больше смотреть на ваши предложения. –

+0

Если вы не хотите поколебать мир, пока вы используете устаревший код рефакторинга, я думаю, что ваш лучший вариант - скопировать объект в обработчик, прежде чем вы его мутируете. Это небольшое изменение, если это не класс с большим количеством полей и без копирования c'tor. –

Смежные вопросы