Сохранение состояния в Netty ChannelHandler

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

Например, используя этот обработчик для каждого соединения:

class Handler extends SimpleChannelUpstreamHandler {
        int count = 0;

        @Override
        public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
            ++count;
        }
}

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

Так ли это? или внутри netty происходит какая-то синхронизация, из-за которой запись в поле count сбрасывается?


person S-C    schedule 29.11.2011    source источник


Ответы (2)


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

Если вы добавляете обработчик выполнения в свой конвейер, то все в порядке, если вы используете Netty's OrderedMemoryAwareThreadPoolExecutor.

Если вы обращаетесь к своему конвейеру из потока, отличного от Netty, или у вас есть не-OrderedMemoryAwareThreadPoolExecutor в вашем конвейере, вам нужна синхронизация.

Я рекомендую просмотреть следующие темы в архивах форумов пользователей Netty.

http://netty.markmail.org/search/?q=Memory+visibility+in+handlers#query:Memory%20visibility%20in%20handlers+page:1+mid:cmtw5omcxbg67sho+state:results

http://netty.markmail.org/search/?q=Periodic%20TimerTask%20in#query:Periodic%20TimerTask%20in+page:2+mid:vwahepiois4eqwkp+state:results

person johnstlr    schedule 30.11.2011
comment
Спасибо! это то, что я искал, Netty гарантирует, что данный экземпляр конвейера всегда вызывается из одного и того же рабочего потока. - person S-C; 30.11.2011

Когда вы создаете Netty ChannelPipeline, если вы добавляете один и тот же экземпляр вашего Handler во все каналы, тогда да, несколько потоков будут читать/изменять ваши данные.

Если вы создадите новый экземпляр Handler для каждого канала в своем конвейере, как показано ниже, вы в безопасности, только один поток получит доступ к обработчику в pipeline за один раз.

ChannelPipeline p = Channels.pipeline();
pipeline.addLast("handler", new Handler());

Также взгляните на Netty ChannelLocal. , это похоже на java ThreadLocal, и вы можете установить состояние для каждого канала

person Abe    schedule 29.11.2011
comment
Верно, я полагал, что только один поток будет когда-либо обращаться к обработчику одновременно, но это не гарантирует, что второй поток, который обращается к обработчику, увидит изменения, сделанные первым потоком, если только netty не выполняет изменчивую запись или что-то еще, что гарантирует видимость. - person S-C; 29.11.2011