EventLoop
EventLoop本质上就是一个Selector+一个单线程执行器。里面的run方法处理channel上源源不断的io事件
EventLoop它继承两个类
- 第一个是继承netty自己的OrderedEventExecutor接口
- 第二个是继承java.util.concurrent.ScheduledExecutorService接口
我们一般是不会直接用EventLoop 一般是使用EventLoopGroup。
因为我们肯定是需要多个EventLoop,也就相当于是需要多个线程来处理各种事件,而EventLoop本质又是一个单线程执行器。
channel一般会调用EventLoopGroup中的register()方法来绑定其中一个EventLoop,之后这个channel的io事件都又该EventLoop来处理。
创建EventLoopGroup
public static void main(String[] args) {
// 创建EventLoopGroup,它是一个接口,常用的使用就是NioEventLoopGroup
// 它可以处理io事件,普通任务,定时任务
// 还有另一个实现 DefaultEventLoop 它可以处理普通任务,定时任务。适用于一些没有io事件发生的场景
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
}
一般情况我们都没有往构造方法里面写参数,可以写一个int表示要创建几个EventLoop也就是创建几个线程。那默认会创建几个嘞?
在源码中的第一层,这里默认写了0,然后再一直点下去。
public NioEventLoopGroup() {
this(0);
}
然后到了父类MultithreadEventLoopGroup类
public abstract class MultithreadEventLoopGroup ... {
// 这里最后是创建了cpu核数的两倍 NettyRuntime.availableProcessors()就是cpu核数
private static final int DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
// 如果为0就采用一个默认的静态常量的值DEFAULT_EVENT_LOOP_THREADS
protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {
super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
}
}
可以发现,如果我们指定了EventLoop的数量那就以我们指定的为准,如果没有指定那就是采用的cou核数*2
执行普通任务和定时任务
package com.hs.nettyPrimary;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit