Сохранение состояния в Netty ChannelHandler - PullRequest
4 голосов
/ 29 ноября 2011

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

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

class Handler extends SimpleChannelUpstreamHandler {
        int count = 0;

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

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

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

Ответы [ 2 ]

7 голосов
/ 30 ноября 2011

Если у вас нет исполнителя в вашем конвейере, и вы выполняете свои обработчики исключительно в рабочих потоках ввода-вывода, тогда у вас все в порядке, поскольку 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

2 голосов
/ 29 ноября 2011

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

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

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

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

...