2011-11-29 74 views
4

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

例如,使用在每个连接的基础这个处理程序:

class Handler extends SimpleChannelUpstreamHandler { 
     int count = 0; 

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

我希望从一个网状线程池中的许多不同的线程将调用此方法,但不能同时使用,并有可能看到一个不一致的观点,导致计数不准确。

这是这种情况?或者netty内部是否有某种同步进行,这会导致写入计数字段的内容被刷新?

回答

6

状态。如果你没有在你的管道的执行,并执行你的处理程序纯粹在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

+0

谢谢!这就是我所寻找的,“Netty保证给定的管道实例始终从同一个工作线程回调” –

2

当您创建的Netty ChannelPipeline如果您添加Handler相同实例所有通道则是,多个线程将读取/修改数据。

如果您创建的Handler每个通道在您的管道,如下图所示,那么你是安全的,只有一个线程将在同一时间访问在pipeline处理程序,然后一个新的实例。

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

而且看一看的Netty ChannelLocal,它像java ThreadLocal,你可以设置每个通道的基础

+0

权,我想,只有一个线程将永远访问处理器并行但dosent保证访问的处理器将看到第一个线程所做的更改,除非第二个线程netty正在做一个易变的写或其他保证可见性的东西 –