idea启动报错if you already_netty服务端启动流程总结

先看个流程图

adcf65437be114eaca2af9ab9654f907.png

服务端启动做了哪些事情

//创建EventLoopGroup,初始化所有的EventLoop,初始化线程工具 EventLoopGroup bossEventLoopGroup = new NioEventLoopGroup(2); executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());//创建channel,初始化channel的pipelinechannel = channelFactory.newChannel();//为channel的pipeline绑定ChannelHandler----使用EventLoop(与channel关联的)异步执行 p.addLast(new ChannelInitializer() {            @Override            public void initChannel(final Channel ch) throws Exception {                final ChannelPipeline pipeline = ch.pipeline();                ChannelHandler handler = config.handler();                if (handler != null) {                    pipeline.addLast(handler);                }                ch.eventLoop().execute(new Runnable() {                    @Override                    public void run() {                        pipeline.addLast(new ServerBootstrapAcceptor(                                ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));                    }                });            }        });//选择EventLoopGroup的一个EventLoop的selector,将channel注册上去ChannelFuture regFuture = config().group().register(channel);//将channel注册到一个绑定的EventLoop的selector----使用EventLoop(与channel关联的)异步执行eventLoop.execute(new Runnable() {  @Override  public void run() {    register0(promise);  }});//绑定Channel到指定的端口-----使用EventLoop(与channel关联的)异步执行private static void doBind0(            final ChannelFuture regFuture, final Channel channel,            final SocketAddress localAddress, final ChannelPromise promise) {        channel.eventLoop().execute(new Runnable() {            @Override            public void run() {                if (regFuture.isSuccess()) {                    channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);                } else {                    promise.setFailure(regFuture.cause());                }            }        });    }                12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849

EventLoop的execute方法

//EventLoop的execute方法public void execute(Runnable task) {    if (task == null) {        throw new NullPointerException("task");    }  //判断当前EventLoop持有线程有没有启动    boolean inEventLoop = inEventLoop();  //启动过,直接添加到任务队列    if (inEventLoop) {        addTask(task);    } else {        //没启动,先启动EventLoop唯一的线程,然后添加任务        startThread();        addTask(task);        if (isShutdown() && removeTask(task)) {            reject();        }    }    if (!addTaskWakesUp && wakesUpForTask(task)) {        wakeup(inEventLoop);    }}123456789101112131415161718192021222324

EventLoop的轮训方法

//轮训处理方法protected void run() {    for (;;) {        try {            switch (selectStrategy.calculateStrategy(selectNowSupplier, hasTasks())) {            try {                        processSelectedKeys();                    } finally {                        final long ioTime = System.nanoTime() - ioStartTime;                        runAllTasks(ioTime * (100 - ioRatio) / ioRatio);                    }                //省去......                //1.轮训方法会去task队列获取任务//2.channel的pipeline绑定ChannelHandler,会在这里触发回调//3.channel注册到一个绑定的EventLoop的selector,会在这里触发回调 //4.Channel到指定的端口绑定,会在这里触发回调 //5.上面2-4都是初始化异步做的事情,都丢到channel关联的EventLoop去做                123456789101112131415161718

总结

1.启动流程中做的事情还是 创建selector,channel,绑定端口,轮训selector  其实和我们使用jdk nio编写一个网络编程是没本质区别的,只不过是做了组件化  的封装,扩展性更强2.netty的EventLoop其实就像一个有一个线程的线程池,去轮训处理绑定在当前 EventLoop的所有channel的所有提交的任务,EventLoop也有拒绝策略,线程 工厂,任务队列等,只不过没有回收策略,这和他是一个具有NIO编程的强功能性 相关,注定是个长任务,而且也就一个线程,所以没必要 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值