zoukankan      html  css  js  c++  java
  • 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();
                    }
                }
            });
  • 相关阅读:
    常用日期函数介绍
    常用数学函数介绍
    oracle 常用sql字符函数介绍
    centos6.5 相关命令
    Kettle5.4.0 java.lang.OutOfMemoryError
    oracle多表连接方式Hash Join Nested Loop Join Merge Join
    CONNECT_BY_ROOT
    设置Oracle PL/SQL时间显示格式NLS_TIMESTAMP_FORMAT
    INSTR代替NOT LIKE
    多表插入
  • 原文地址:https://www.cnblogs.com/mxz1994/p/9471706.html
Copyright © 2011-2022 走看看