将状态保存在Netty ChannelHandler中

时间:2011-11-29 00:31:22

标签: java multithreading netty

netty文档建议在ChannelHandlers中使用实例变量来跟踪信道状态。它没有提到您应该使用volatile变量或使用任何其他同步技术来确保跨线程存在一致的视图。

例如,基于每个连接使用此处理程序:

class Handler extends SimpleChannelUpstreamHandler {
        int count = 0;

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

我希望来自netty线程池的许多不同线程会调用此方法,尽管不是同时发生的,并且可能会看到不一致的视图,从而导致计数不准确。

是这样的吗?或者在netty内部是否存在某种同步会导致对count字段的写入被刷新?

2 个答案:

答案 0 :(得分:7)

如果您的管道中没有执行程序,并且仅在I / O工作线程中执行处理程序,那么您就可以了,因为Netty保证始终从同一个工作线程调用给定的管道实例

如果您正在向管道添加执行处理程序,那么如果您使用的是Netty的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

答案 1 :(得分:2)

如果您将ChannelPipeline相同实例添加到所有渠道,则创建Netty Handler,然后是,多个线程将读取/修改您的数据。< / p>

如果您在管道中为每个频道创建Handler的新实例,如下所示,那么您是安全的,只有一个帖子才能访问pipeline中的处理程序那时候。

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

另请查看Netty ChannelLocal,它类似于java ThreadLocal,您可以基于每个渠道设置状态