netty学习-EventLoop组件

netty--EventLoop组件

  • EventLoop
    • NioEventLoopGroup
      • 无参构造器
      • 获取下一个EventLoop事件循环对象
      • 执行普通任务
      • 执行定时任务
      • 执行IO任务

EventLoop

EventLoop其实就是一个单线程执行器,同时内部维护了一个Selector(selector是多路复用器),里面的run方法处理Channel上源源不断的IO事件,而EventLoopGroup就是一组EventLoop,Channel一般会调用EventLoopGroup的register方法来绑定一个EventLoop,后续这个Channel上的io事件都会由这个EventLoop来处理保证线程安全

NioEventLoopGroup

NioEventLoopGroup能处理io事件,也能处理普通任务和定时任务

无参构造器

在这里插入图片描述
发现又传个了另一个构造器。
netty学习-EventLoop组件_第1张图片
一点一点点下去发现后面判断了如果是0的话就用一个默认线程数
netty学习-EventLoop组件_第2张图片

Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2))

默认线程数是处理器核心数*2,然后和1去比较用数字较大的,也就是说最少都是一个线程

netty学习-EventLoop组件_第3张图片
我的电脑是8核,8*2=16个线程

获取下一个EventLoop事件循环对象

采用轮询的机制

@Slf4j
public class MultiThreadServer {
     
    public static void main(String[] args) {
     
        // 设置线程数2个 那么事件循环对象就是2个
        NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(2);
        // 采用轮询的机制
        System.out.println(nioEventLoopGroup.next());
        System.out.println(nioEventLoopGroup.next());
        System.out.println(nioEventLoopGroup.next());
        System.out.println(nioEventLoopGroup.next());
    }
}

netty学习-EventLoop组件_第4张图片

执行普通任务

netty学习-EventLoop组件_第5张图片
NioEventLoopGroup的继承关系来看它本身也是一个线程池对象,能执行普通任务

@Slf4j
public class MultiThreadServer {
     
    public static void main(String[] args) {
     
        NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(2);
        nioEventLoopGroup.submit(() -> System.out.println("你好世界!"));
        nioEventLoopGroup.execute(() -> System.out.println("HelloWorld!"));
    }
}

netty学习-EventLoop组件_第6张图片

执行定时任务

netty学习-EventLoop组件_第7张图片

执行IO任务

服务端

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import lombok.extern.slf4j.Slf4j;

@Slf4j(topic = "w.Test1")
public class HelloServer {
     
    public static void main(String[] args) {
     
        // 创建启动器
        new ServerBootstrap()
                // 创建EventLoop事件监听处理组
                .group(new NioEventLoopGroup())
                // 设置ServerSocketChannel的实现NioServerSocketChannel
                .channel(NioServerSocketChannel.class)
                // 设置处理器
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
     
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
     
                        // 添加处理工序 处理stringBuf为字符串
                        ch.pipeline().addLast(new StringDecoder());
                        // 自定义处理器
                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
     
                            // 监听读时间
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
     
                                // 打印上一步转换好的字符串
                                log.debug((String) msg);
                            }
                        });
                    }
                }).bind(8080); // 绑定的监听端口
    }
}

客户端

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
@Slf4j(topic = "w.Test1")
public class HelloClient {
     
    public static void main(String[] args) throws InterruptedException {
     
        //1 启动类
        new Bootstrap()
                // 2.添加EventLoop
                .group(new NioEventLoopGroup())
                // 3.选择客服端channel实现
                .channel(NioSocketChannel.class)
                // 4 添加处理器
                .handler(new ChannelInitializer<NioSocketChannel>() {
     
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
     
                        ch.pipeline().addLast(new StringEncoder());
                    }
                    // 连接地址
                }).connect(new InetSocketAddress("127.0.0.1", 8080))
                .sync()
                .channel()
                .writeAndFlush("hello world");
    }
}

先启动服务端,准备接收请求,然后开启客户端发送信息
netty学习-EventLoop组件_第8张图片
成功接收到客服端发送的信息

学习资料来源B站 黑马程序员Netty全套教程

你可能感兴趣的:(笔记,netty,epoll)