Netty源码(一)EventLoopGroup

EventLoopGroup

用过Netty的都知道,EventLoopGroup包含多个EventLoop,而一个EventLoop和一个线程绑定,一个Channel绑定到一个EventLoop上,一个EventLoop可以管理多个Channel
EventLoop用来处理Channel的io事件

类继承结构

在这里插入图片描述

EventExecutorGroup

EventExecutorGroup主要提供next方法来获取EventExecutor,除此之外可以用来管理EventExecutor的生命周期以及关闭它们
在这里插入图片描述
可以看到除了继承的接口的方法,主要提供了一个next方法

EventExecutor

EventExecutor是特殊的EventExecutorGroup,主要提供了一些简便的方法来判断一个线程是否在一个event loop中执行

public interface EventExecutor extends EventExecutorGroup {

    /**
     * Returns a reference to itself.
     */
    @Override
    EventExecutor next();

    /**
     * Return the {@link EventExecutorGroup} which is the parent of this {@link EventExecutor},
     */
    EventExecutorGroup parent();

    /**
     * Calls {@link #inEventLoop(Thread)} with {@link Thread#currentThread()} as argument
     */
    boolean inEventLoop();

    /**
     * Return {@code true} if the given {@link Thread} is executed in the event loop,
     * {@code false} otherwise.
     */
    boolean inEventLoop(Thread thread);

    /**
     * Return a new {@link Promise}.
     */
    <V> Promise<V> newPromise();

    /**
     * Create a new {@link ProgressivePromise}.
     */
    <V> ProgressivePromise<V> newProgressivePromise();

    /**
     * Create a new {@link Future} which is marked as successes already. So {@link Future#isSuccess()}
     * will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also
     * every call of blocking methods will just return without blocking.
     */
    <V> Future<V> newSucceededFuture(V result);

    /**
     * Create a new {@link Future} which is marked as fakued already. So {@link Future#isSuccess()}
     * will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also
     * every call of blocking methods will just return without blocking.
     */
    <V> Future<V> newFailedFuture(Throwable cause);
}

EventLoopGroup

EventLoopGroup是特殊的EventExecutorGroup,主要添加了注册Channel的能力

public interface EventLoopGroup extends EventExecutorGroup {
    /**
     * Return the next {@link EventLoop} to use
     */
    @Override
    EventLoop next();

    /**
     * Register a {@link Channel} with this {@link EventLoop}. The returned {@link ChannelFuture}
     * will get notified once the registration was complete.
     */
    ChannelFuture register(Channel channel);

    /**
     * Register a {@link Channel} with this {@link EventLoop}. The passed {@link ChannelFuture}
     * will get notified once the registration was complete and also will get returned.
     */
    ChannelFuture register(Channel channel, ChannelPromise promise);
}

EventLoop

用来处理注册到EventLoopGroup的channel的所有io事件

public interface EventLoop extends EventExecutor, EventLoopGroup {
    @Override
    EventLoopGroup parent();
}

AbstractEventExecutorGroup

可以简单地看下其中的几个方法

public abstract class AbstractEventExecutorGroup implements EventExecutorGroup {
	@Override
    public Future<?> submit(Runnable task) {
        return next().submit(task);
    }
    
    @Override
    public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
        return next().schedule(command, delay, unit);
    }
    
    @Override
    public <T> List<java.util.concurrent.Future<T>> invokeAll(
            Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
        return next().invokeAll(tasks, timeout, unit);
    }
}

可以看到submit schedule invokeAll等方法都是将请求透传给next方法返回的对象

NioEventLoopGroup

下面沿着NioEventLoopGroup的继承路径来从上到下看下NioEventLoopGroup的父类

MultithreadEventExecutorGroup

EventExecutorGroup的实现,使用多个线程来执行任务

构造方法
protected MultithreadEventExecutorGroup(int nThreads, ThreadFactory threadFactory, Object... args) {
    if (nThreads <= 0) {
        throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));
    }

	// 创建线程工厂DefaultThreadFactory
    if (threadFactory == null) {
        threadFactory = newDefaultThreadFactory();
    }
	
	// 创建eventExecutor数组
    children = new SingleThreadEventExecutor[nThreads];
    // 创建指定个数的eventExecutor
    for (int i = 0; i < nThreads; i ++) {
        boolean success = false;
        try {
        	// 通过线程工厂和参数来创建一个eventExecutor
        	// 具体如何创建由子类来实现
            children[i] = newChild(threadFactory, args);
            success = true;
        } catch (Exception e) {
            // TODO: Think about if this is a good exception type
            throw new IllegalStateException("failed to create a child event loop", e);
        } finally {
        	// 其中一个eventExecutor创建失败
            if (!success) {
            	// 优雅停止之前创建的eventExecutor
                for (int j = 0; j < i; j ++) {
                    children[j].shutdownGracefully();
                }
				
				// 等待eventExecutor停止
                for (int j = 0; j < i; j ++) {
                    EventExecutor e = children[j];
                    try {
                        while (!e.isTerminated()) {
                            e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
                        }
                    } catch (InterruptedException interrupted) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        }
    }

	// 创建eventExecutor停止回调监听器
    final FutureListener<Object> terminationListener = new FutureListener<Object>() {
        @Override
        public void operationComplete(Future<Object> future) throws Exception {
            if (terminatedChildren.incrementAndGet() == children.length) {
                terminationFuture.setSuccess(null);
            }
        }
    };
	
	// 每个eventExecutor添加停止回调监听器
    for (EventExecutor e: children) {
        e.terminationFuture().addListener(terminationListener);
    }
}
next
public EventExecutor next() {
	// 通过round robin的方式来获取下一个eventExecutor
    return children[Math.abs(childIndex.getAndIncrement() % children.length)];
}

MultithreadEventLoopGroup

EventLoopGroup的一个实现,使用多个线程来处理任务

构造方法
static {
		// 确定线程的数量
		// 如果指定了io.netty.eventLoopThreads,那么使用其作为线程的个数
		// 否则使用当前机器的处理器个数*2作为线程的个数
        DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
                "io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2));

        if (logger.isDebugEnabled()) {
            logger.debug("-Dio.netty.eventLoopThreads: {}", DEFAULT_EVENT_LOOP_THREADS);
        }
    }

/**
 * @see {@link MultithreadEventExecutorGroup#MultithreadEventExecutorGroup(int, ThreadFactory, Object...)}
 */
protected MultithreadEventLoopGroup(int nThreads, ThreadFactory threadFactory, Object... args) {
    super(nThreads == 0? DEFAULT_EVENT_LOOP_THREADS : nThreads, threadFactory, args);
}
register
@Override
public ChannelFuture register(Channel channel) {
    return next().register(channel);
}

@Override
public ChannelFuture register(Channel channel, ChannelPromise promise) {
    return next().register(channel, promise);
}
next
@Override
public EventLoop next() {
    return (EventLoop) super.next();
}

NioEventLoopGroup

是MultithreadEventLoopGroup的一个实现类,适用于基于NIO selector的channel

构造方法

从构造方法的入参可以看出,主要需要指定需要使用多少个线程

public NioEventLoopGroup() {
        this(0);
}

/**
* Create a new instance using the specified number of threads, {@link ThreadFactory} and the
* {@link SelectorProvider} which is returned by {@link SelectorProvider#provider()}.
*/
public NioEventLoopGroup(int nThreads) {
   this(nThreads, null);
}

/**
* Create a new instance using the specified number of threads, the given {@link ThreadFactory} and the
* {@link SelectorProvider} which is returned by {@link SelectorProvider#provider()}.
*/
public NioEventLoopGroup(int nThreads, ThreadFactory threadFactory) {
   this(nThreads, threadFactory, SelectorProvider.provider());
}

/**
* Create a new instance using the specified number of threads, the given {@link ThreadFactory} and the given
* {@link SelectorProvider}.
*/
public NioEventLoopGroup(
       int nThreads, ThreadFactory threadFactory, final SelectorProvider selectorProvider) {
   super(nThreads, threadFactory, selectorProvider);
}
newChild

这里创建的EventExecutor是NioEventLoop类型的

@Override
protected EventExecutor newChild(
        ThreadFactory threadFactory, Object... args) throws Exception {
    return new NioEventLoop(this, threadFactory, (SelectorProvider) args[0]);
}

OioEventLoopGroup

下面沿着OioEventLoopGroup的继承路径从上到下看下OioEventLoopGroup的父类

ThreadPerChannelEventLoopGroup

为每个注册的channel都新建一个EventLoop
只有在注册channel的时候才会创建EventLoop

构造方法
protected ThreadPerChannelEventLoopGroup(int maxChannels, ThreadFactory threadFactory, Object... args) {
	// maxChannel代表当前EventLoopGroup能够处理的channel的最大数量
    if (maxChannels < 0) {
        throw new IllegalArgumentException(String.format(
                "maxChannels: %d (expected: >= 0)", maxChannels));
    }
    if (threadFactory == null) {
        throw new NullPointerException("threadFactory");
    }

    if (args == null) {
        childArgs = EmptyArrays.EMPTY_OBJECTS;
    } else {
        childArgs = args.clone();
    }

    this.maxChannels = maxChannels;
    this.threadFactory = threadFactory;

    tooManyChannels = new ChannelException("too many channels (max: " + maxChannels + ')');
    tooManyChannels.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE);
}
next
public EventLoop next() {
 throw new UnsupportedOperationException();
}
register
public ChannelFuture register(Channel channel) {
    if (channel == null) {
        throw new NullPointerException("channel");
    }
    try {
    	// 获取一个EventLoop,将当前的channel注册上去
        return nextChild().register(channel);
    } catch (Throwable t) {
        return channel.newFailedFuture(t);
    }
}
private EventLoop nextChild() throws Exception {
    if (shuttingDown) {
        throw new RejectedExecutionException("shutting down");
    }
	// 首先尝试复用空闲的eventLoop
    ThreadPerChannelEventLoop loop = idleChildren.poll();
    if (loop == null) {
    	// 如果没有空闲的eventLoop
    	// 判断当前正在处理的channel数量是否超过上限,如果超过上限会抛出异常
        if (maxChannels > 0 && activeChildren.size() >= maxChannels) {
            throw tooManyChannels;
        }
        // 创建一个新的eventLoop
        loop = newChild(childArgs);
        loop.terminationFuture().addListener(childTerminationListener);
    }
    // 将新创建的eventLoop放入到activeChildren这个集合中
    activeChildren.add(loop);
    return loop;
}
protected ThreadPerChannelEventLoop newChild(
            @SuppressWarnings("UnusedParameters") Object... args) throws Exception {
    return new ThreadPerChannelEventLoop(this);
}

OioEventLoopGroup

构造方法

可以看到构造方法主要指定的就是最多注册的channle个数

public OioEventLoopGroup() {
    this(0);
}

/**
 * Create a new {@link OioEventLoopGroup}.
 *
 * @param maxChannels       the maximum number of channels to handle with this instance. Once you try to register
 *                          a new {@link Channel} and the maximum is exceed it will throw an
 *                          {@link ChannelException} on the {@link #register(Channel)} and
 *                          {@link #register(Channel, ChannelPromise)} method.
 *                          Use {@code 0} to use no limit
 */
public OioEventLoopGroup(int maxChannels) {
    this(maxChannels, Executors.defaultThreadFactory());
}

/**
 * Create a new {@link OioEventLoopGroup}.
 *
 * @param maxChannels       the maximum number of channels to handle with this instance. Once you try to register
 *                          a new {@link Channel} and the maximum is exceed it will throw an
 *                          {@link ChannelException} on the {@link #register(Channel)} and
 *                          {@link #register(Channel, ChannelPromise)} method.
 *                          Use {@code 0} to use no limit
 * @param threadFactory     the {@link ThreadFactory} used to create new {@link Thread} instances that handle the
 *                          registered {@link Channel}s
 */
public OioEventLoopGroup(int maxChannels, ThreadFactory threadFactory) {
    super(maxChannels, threadFactory);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值