EventLoop介绍

在Netty中使用EventLoop接口代表事件循环,EventLoop是从EventExecutor和ScheduledExecutorService扩展而来,所以可以讲任务直接交给EventLoop执行

可以进行各种骚操作

每个通道需要注册到一个EventLoop来处理IO或事件,这是在引导过程中自动完成
        //nio
        java.nio.channels.SocketChannel mySocket = java.nio.channels.SocketChannel.open();
        //netty
        SocketChannel ch = new NioSocketChannel(mySocket);
        EventLoopGroup group = new NioEventLoopGroup();
        //register channel
        ChannelFuture registerFuture = group.register(ch);
        //de-register channel
        ChannelFuture deregisterFuture = ch.deregister();

EventLoop.register(...)和Channel.deregister(...)都是非阻塞异步的,也就是说它们可能不会理解执行完成,可能稍后完成。它们返回ChannelFuture,我们在需要进一步操作或确认完成操作时可以添加一个ChannelFutureLister或在ChannelFuture上同步等待至完成;选择哪一种方式看实际需求,一般建议使用ChannelFutureLister,应避免阻塞。

挂起IO处理

        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group).channel(NioSocketChannel.class)
                .handler(new SimpleChannelInboundHandler<ByteBuf>() {
                    @Override
                    protected void channelRead0(ChannelHandlerContext ctx,
                            ByteBuf msg) throws Exception {
                        //remove this ChannelHandler and de-register
                        ctx.pipeline().remove(this);
                        ctx.deregister();
                    }
                });
        ChannelFuture future = bootstrap.connect(
                new InetSocketAddress("www.baidu.com", 80)).sync();
        //....
        Channel channel = future.channel();
        //re-register channel and add ChannelFutureLister
        group.register(channel).addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if(future.isSuccess()){
                    System.out.println("Channel registered");
                }else{
                    System.out.println("register channel on EventLoop fail");
                    future.cause().printStackTrace();
                }
            }
        });

迁移通道到另一个事件循环

 另一个取消注册和注册一个Channel的用例是将一个活跃的Channel移到另一个EventLoop,有下面一些原因可能导致需要这么做:
  • 当前EventLoop太忙碌,需要将Channel移到一个不是很忙碌的EventLoop;
  • 终止EventLoop释放资源同时保持活跃Channel可以继续使用;
  • 迁移Channel到一个执行级别较低的非关键业务的EventLoop中。
        EventLoopGroup group = new NioEventLoopGroup();
        final EventLoopGroup group2 = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();
        b.group(group).channel(NioSocketChannel.class)
                .handler(new SimpleChannelInboundHandler<ByteBuf>() {
                    @Override
                    protected void channelRead0(ChannelHandlerContext ctx,
                            ByteBuf msg) throws Exception {
                        // remove this channel handler and de-register
                        ctx.pipeline().remove(this);
                        ChannelFuture f = ctx.deregister();
                        // add ChannelFutureListener
                        f.addListener(new ChannelFutureListener() {
                            @Override
                            public void operationComplete(ChannelFuture future)
                                    throws Exception {
                                // migrate this handler register to group2
                                group2.register(future.channel());
                            }
                        });
                    }
                });
        ChannelFuture future = b.connect("www.baidu.com", 80);
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future)
                    throws Exception {
                if (future.isSuccess()) {
                    System.out.println("connection established");
                } else {
                    System.out.println("connection attempt failed");
                    future.cause().printStackTrace();
                }
            }
        });
原文地址:https://www.cnblogs.com/mxz1994/p/9471706.html