Netty中的并发性

5

我正在实现ChannelInboundHandlerAdapter,并且有一个关于并发的问题。是否需要使其线程安全?我的意思是,我必须为每个客户端存储一些状态以便于他们的会话。

public class Impl extends ChannelInboundHandlerAdapter{
    private List<Integer> someState;
    //

    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        int size = someState.size();  //Should I worry about memory consitency here?
        //...
    }
}

问题是,如果每个请求之间的channelRead方法由不同的线程调用,我将不得不设置一些内存屏障。

这是必需的吗?还是Netty自己会处理?

1个回答

8

针对Netty 4.x版本

明确定义的线程模型

在3.x版本中,没有一个明确定义的线程模型,尽管在3.5版本中曾试图修复其不一致性。4.0定义了严格的线程模型,帮助用户编写一个ChannelHandler而无需过多担心线程安全问题。

  • 除非ChannelHandler被注解为@Sharable,否则Netty永远不会同时调用ChannelHandler的方法。这适用于所有类型的handler方法——入站、出站或生命周期事件处理器方法。
    • 用户不再需要同步入站或出站事件处理程序方法。
    • 4.0禁止添加未经注解@Sharable的ChannelHandler超过一次。
  • 每个由Netty进行的ChannelHandler方法调用之间都有先于发生的关系。
    • 用户不需要定义易失性字段来保持处理程序的状态。
  • 用户可以在将处理程序添加到ChannelPipeline时指定EventExecutor。
    • 如果指定了,ChannelHandler的处理程序总是由指定的EventExecutor调用。
    • 如果未指定,处理程序将始终由其关联通道注册到的EventLoop调用。
  • 分配给处理程序或通道的EventExecutor和EventLoop始终是单线程的。
    • 处理程序方法将始终由同一线程调用。
    • 如果指定了多线程EventExecutor或EventLoop,将首先选择其中一个线程,然后使用已选择的线程直至注销。
    • 如果在同一管道中的两个处理程序被分配不同的EventExecutors,则它们将同时被调用。即使仅由同一管道中的处理程序访问共享数据,如果有多个处理程序访问共享数据,用户也必须注意线程安全性问题。
  • 添加到ChannelFuture的ChannelFutureListeners始终由与该Future关联通道的EventLoop线程调用。
  • 可以使用ChannelHandlerInvoker来控制Channel事件的顺序。DefaultChannelHandlerInvoker立即从EventLoop线程执行事件,并将其他线程的事件作为Runnable对象在EventExecutor上执行。请参见以下示例,了解从EventLoop线程和其他线程与通道交互时可能产生的影响。

(强调是我的)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接