Netty组件源码解析(3)

面试官:Netty中的缓冲区为什么比原生NIO更高效 Netty自己的ByteBuf ByteBuf是为了解决ByteBuffer的问题和满足网络应用程序开发人员的日常需求而设计的. JDK中ByteBuffer的缺点: 无法动态扩容长度是固定的,不能动态扩展和收缩,当数据大于ByteBuffer容量时,会发生索引越界异常. API使用复杂读写的时候需要手动调用flip()和rewind()等方法,使用时需要非常谨慎的使用这些api,否则容易出现错误. ByteBuf做了哪些增强? API操作便捷性 动态扩容 多种ByteBuf实现 内.. 阅读详情

SingleThreadEventLoop 基于单线程的EventLoop抽象类,将Channel注册到EventLoop上

public abstract class SingleThreadEventLoop extends SingleThreadEventExecutor implements EventLoop {
	//默认任务队列最大数量**加粗样式**
    protected static final int DEFAULT_MAX_PENDING_TASKS = Math.max(16,
            SystemPropertyUtil.getInt("io.netty.eventLoop.maxPendingTasks", Integer.MAX_VALUE));
	//尾部任务队列
    private final Queue<Runnable> tailTasks;

    protected SingleThreadEventLoop(EventLoopGroup parent, ThreadFactory threadFactory, boolean addTaskWakesUp) {
        this(parent, threadFactory, addTaskWakesUp, DEFAULT_MAX_PENDING_TASKS, RejectedExecutionHandlers.reject());
    }

    protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor, boolean addTaskWakesUp) {
        this(parent, executor, addTaskWakesUp, DEFAULT_MAX_PENDING_TASKS, RejectedExecutionHandlers.reject());
    }

    protected SingleThreadEventLoop(EventLoopGroup parent, ThreadFactory threadFactory,
                                    boolean addTaskWakesUp, int maxPendingTasks,
                                    RejectedExecutionHandler rejectedExecutionHandler) {
        super(parent, threadFactory, addTaskWakesUp, maxPendingTasks, rejectedExecutionHandler);
        tailTasks = newTaskQueue(maxPendingTasks);
    }

    protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor,
                                    boolean addTaskWakesUp, int maxPendingTasks,
                                    RejectedExecutionHandler rejectedExecutionHandler) {
        super(parent, executor, addTaskWakesUp, maxPendingTasks, rejectedExecutionHandler);
        tailTasks = newTaskQueue(maxPendingTasks);
    }

    protected SingleThreadEventLoop(EventLoopGroup parent, Executor executor,
                                    boolean addTaskWakesUp, Queue<Runnable> taskQueue, Queue<Runnable> tailTaskQueue,
                                    RejectedExecutionHandler rejectedExecutionHandler) {
        super(parent, executor, addTaskWakesUp, taskQueue, rejectedExecutionHandler);
        tailTasks = ObjectUtil.checkNotNull(tailTaskQueue, "tailTaskQueue");
    }
	//获取所属的EventLoopGroup
    @Override
    public EventLoopGroup parent() {
        return (EventLoopGroup) super.parent();
    }
	//获取自己
    @Override
    public EventLoop next() {
        return (EventLoop) super.next();
    }
	//注册Channel到EventLoop上
    @Override
    public ChannelFuture register(Channel channel) {
        return register(new DefaultChannelPromise(channel, this));
    }

    @Override
    public ChannelFuture register(final ChannelPromise promise) {
        ObjectUtil.checkNotNull(promise, "promise");
        //注册Channel到EventLoop上
        promise.channel().unsafe().register(this, promise);
        //返回ChannelPromise对象
        return promise;
    }

    @Deprecated
    @Override
    public ChannelFuture register(final Channel channel, final ChannelPromise promise) {
        ObjectUtil.checkNotNull(promise, "promise");
        ObjectUtil.checkNotNull(channel, "channel");
        channel.unsafe().register(this, promise);
        return promise;
    }

    @UnstableApi
    public final void executeAfterEventLoopIteration(Runnable task) {
        ObjectUtil.checkNotNull(task, "task");
        //关闭时,拒绝任务
        if (isShutdown()) {
            reject();
        }
		//添加到任务队列
        if (!tailTasks.offer(task)) {
        //添加失败则拒绝任务
            reject(task);
        }

        if (!(task instanceof LazyRunnable) && wakesUpForTask(task)) {
        //唤醒线程
            wakeup(inEventLoop());
        }
    }
	//移除指定任务
    @UnstableApi
    final boolean removeAfterEventLoopIterationTask(Runnable task) {
        return tailTasks.remove(ObjectUtil.checkNotNull(task, "task"));
    }
	//运行完所有任务后,执行tailTasks队列中的任务
    @Override
    protected void afterRunningAllTasks() {
        runAllTasksFrom(tailTasks);
    }
	//队列中是否有任务
    @Override
    protected boolean hasTasks() {
        return super.hasTasks() || !tailTasks.isEmpty();
    }
	//获得队列中的任务数
    @Override
    public int pendingTasks() {
        return super.pendingTasks() + tailTasks.size();
    }

    @UnstableApi
    public int registeredChannels() {
        return -1;
    }
}

NioEventLoop 继承SingleThreadEventLoop抽象类,NIOEventLoop实现类

public final class NioEventLoop extends SingleThreadEventLoop {

    private static final InternalLogger logger = InternalLoggerFactory.getInstance(NioEventLoop.class);
	//清理间隙
    private static final int CLEANUP_INTERVAL = 256;
	//是否禁用SelectionKey的优化,默认开启
    private static final boolean DISABLE_KEY_SET_OPTIMIZATION =
            SystemPropertyUtil.getBoolean("io.netty.noKeySetOptimization", false);
	//少于该N值,不开启空轮询重建新的Selector对象的功能
    private static final int MIN_PREMATURE_SELECTOR_RETURNS = 3;
    //空轮询了N次后,重建新的Selector对象
    private static final int SELECTOR_AUTO_REBUILD_THRESHOLD;

    private final IntSupplier selectNowSupplier = new IntSupplier() {
        @Override
        public int get() throws Exception {
            return selectNow();
        }
    };
//静态代码块
    static {
    //得到bugLevel
        final String key = "sun.nio.ch.bugLevel";
        final String bugLevel = SystemPropertyUtil.get(key);
        if (bugLevel == null) {
            try {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    @Override
                    public Void run() {
                        System.setProperty(key, "");
                        return null;
                    }
                });
            } catch (final SecurityException e) {
                logger.debug("Unable to get/set System Property: " + key, e);
            }
        }
		//初始化
        int selectorAutoRebuildThreshold = SystemPropertyUtil.getInt("io.netty.selectorAutoRebuildThreshold", 512);
        if (selectorAutoRebuildThreshold < MIN_PREMATURE_SELECTOR_RETURNS) {
            selectorAutoRebuildThreshold = 0;
        }
        SELECTOR_AUTO_REBUILD_THRESHOLD = selectorAutoRebuildThreshold;
        if (logger.isDebugEnabled()) {
            logger.debug("-Dio.netty.noKeySetOptimization: {}", DISABLE_KEY_SET_OPTIMIZATION);
            logger.debug("-Dio.netty.selectorAutoRebuildThreshold: {}", SELECTOR_AUTO_REBUILD_THRESHOLD);
        }
    }
	//包装的Selector对象,经过优化
    private Selector selector;
    //未包装的Selector对象
    private Selector unwrappedSelector;
    //注册的SelectionKey集合
    private SelectedSelectionKeySet selectedKeys;
	//SelectionProvider对象,用于创建Selector对象
    private final SelectorProvider provider;

    private static final long AWAKE = -1L;
    private static final long NONE = Long.MAX_VALUE;
	//唤醒标记
    private final AtomicLong nextWakeupNanos = new AtomicLong(AWAKE);
	//Select策略
    private final SelectStrategy selectStrategy;
	//处理Channel的就绪的IO事件,占处理任务的总时间的比例
    private volatile int ioRatio = 50;
    //取消SelectionKey的数量
    private int cancelledKeys;
    //是否需要再次select Selector对象
    private boolean needsToSelectAgain;

    NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,
                 SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler,
                 EventLoopTaskQueueFactory queueFactory) {
        super(parent, executor, false, newTaskQueue(queueFactory), newTaskQueue(queueFactory),
                rejectedExecutionHandler);
        this.provider = ObjectUtil.checkNotNull(selectorProvider, "selectorProvider");
        this.selectStrategy = ObjectUtil.checkNotNull(strategy, "selectStrategy");
        //创建Selector对象
        final SelectorTuple selectorTuple = openSelector();
        this.selector = selectorTuple.selector;
        this.unwrappedSelector = selectorTuple.unwrappedSelector;
    }

    private static Queue<Runnable> newTaskQueue(
            EventLoopTaskQueueFactory queueFactory) {
        if (queueFactory == null) {
            return newTaskQueue0(DEFAULT_MAX_PENDING_TASKS);
        }
        return queueFactory.newTaskQueue(DEFAULT_MAX_PENDING_TASKS);
    }
	//内嵌在NioEventLoop,Selector元组
    private static final class SelectorTuple {
    //未包装的Selector对象
        final Selector unwrappedSelector;
        //Selector对象
        final Selector selector;

        SelectorTuple(Selector unwrappedSelector) {
            this.unwrappedSelector = unwrappedSelector;
            this.selector = unwrappedSelector;
        }

        SelectorTuple(Selector unwrappedSelector, Selector selector) {
            this.unwrappedSelector = unwrappedSelector;
            this.selector = selector;
        }
    }
	//创建NIO Selector对象
    private SelectorTuple openSelector() {
    //创建Selector对象,作为unwrappedSelector
        final Selector unwrappedSelector;
        try {
            unwrappedSelector = provider.openSelector();
        } catch (IOException e) {
            throw new ChannelException("failed to open a new selector", e);
        }
		//禁用Selectionkey的优化,则直接返回SelectorTuple对象
        if (DISABLE_KEY_SET_OPTIMIZATION) {
            return new SelectorTuple(unwrappedSelector);
        }
		//获得SelectorImpl类
        Object maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                try {
                //成功则返回该类
                    return Class.forName(
                            "sun.nio.ch.SelectorImpl",
                            false,
                            PlatformDependent.getSystemClassLoader());
                } catch (Throwable cause) {
                //失败则返回该异常
                    return cause;
                }
            }
        });
// 获得 SelectorImpl 类失败,则直接返回 SelectorTuple 对象
        if (!(maybeSelectorImplClass instanceof Class) ||
            !((Class<?>) maybeSelectorImplClass).isAssignableFrom(unwrappedSelector.getClass())) {
            if (maybeSelectorImplClass instanceof Throwable) {
                Throwable t = (Throwable) maybeSelectorImplClass;
                logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, t);
            }
            return new SelectorTuple(unwrappedSelector);
        }

        final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;
        //创建SelectedSelectionKeySet对象
        final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();
		//设置SelectedSelectionKeySet对象到unwrappedSelector
        Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                try {
                //获得selectedKeys和publicSelectedKeys的Field
                    Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");
                    Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");
                    if (PlatformDependent.javaVersion() >= 9 && PlatformDependent.hasUnsafe()) {
                        long selectedKeysFieldOffset = PlatformDependent.objectFieldOffset(selectedKeysField);
                        long publicSelectedKeysFieldOffset =
                                PlatformDependent.objectFieldOffset(publicSelectedKeysField);

                        if (selectedKeysFieldOffset != -1 && publicSelectedKeysFieldOffset != -1) {
                            PlatformDependent.putObject(
                                    unwrappedSelector, selectedKeysFieldOffset, selectedKeySet);
                            PlatformDependent.putObject(
                                    unwrappedSelector, publicSelectedKeysFieldOffset, selectedKeySet);
                            return null;
                        }
                    }
					//设置Field可访问
                    Throwable cause = ReflectionUtil.trySetAccessible(selectedKeysField, true);
                    if (cause != null) {
                        return cause;
                    }
                    cause = ReflectionUtil.trySetAccessible(publicSelectedKeysField, true);
                    if (cause != null) {
                        return cause;
                    }
					//设置SelectedSelectionKeySet对象到unwrappedSelector的Field中
                    selectedKeysField.set(unwrappedSelector, selectedKeySet);
                    publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);
                    return null;
                } catch (NoSuchFieldException e) {
                    return e;
                } catch (IllegalAccessException e) {
                    return e;
                }
            }
        });
		//设置SelectedSelectionKeySet对象到unwrappedSelector中失败,则直接返回Selector
        if (maybeException instanceof Exception) {
            selectedKeys = null;
            Exception e = (Exception) maybeException;
            logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, e);
            return new SelectorTuple(unwrappedSelector);
        }
        // 设置 SelectedSelectionKeySet 对象到 selectedKeys 中
        selectedKeys = selectedKeySet;
        logger.trace("instrumented a special java.util.Set into: {}", unwrappedSelector);
        // 创建 SelectedSelectionKeySetSelector 对象
        return new SelectorTuple(unwrappedSelector,
                                 new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet));
    }

    public SelectorProvider selectorProvider() {
        return provider;
    }
	//创建任务队列
    @Override
    protected Queue<Runnable> newTaskQueue(int maxPendingTasks) {
        return newTaskQueue0(maxPendingTasks);
    }

    private static Queue<Runnable> newTaskQueue0(int maxPendingTasks) {
        return maxPendingTasks == Integer.MAX_VALUE ? PlatformDependent.<Runnable>newMpscQueue()
                : PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks);
    }
	//注册NIO Channel到Selector上
    public void register(final SelectableChannel ch, final int interestOps, final NioTask<?> task) {
        ObjectUtil.checkNotNull(ch, "ch");
        if (interestOps == 0) {
            throw new IllegalArgumentException("interestOps must be non-zero.");
        }
        if ((interestOps & ~ch.validOps()) != 0) {
            throw new IllegalArgumentException(
                    "invalid interestOps: " + interestOps + "(validOps: " + ch.validOps() + ')');
        }
        ObjectUtil.checkNotNull(task, "task");

        if (isShutdown()) {
            throw new IllegalStateException("event loop shut down");
        }

        if (inEventLoop()) {
            register0(ch, interestOps, task);
        } else {
            try {
                submit(new Runnable() {
                    @Override
                    public void run() {
                        register0(ch, interestOps, task);
                    }
                }).sync();
            } catch (InterruptedException ignore) {
                // Even if interrupted we did schedule it so just mark the Thread as interrupted.
                Thread.currentThread().interrupt();
            }
        }
    }

    private void register0(SelectableChannel ch, int interestOps, NioTask<?> task) {
        try {
            ch.register(unwrappedSelector, interestOps, task);
        } catch (Exception e) {
            throw new EventLoopException("failed to register a channel", e);
        }
    }

    public int getIoRatio() {
        return ioRatio;
    }
    //设置ioRatio属性
    public void setIoRatio(int ioRatio) {
        if (ioRatio <= 0 || ioRatio > 100) {
            throw new IllegalArgumentException("ioRatio: " + ioRatio + " (expected: 0 < ioRatio <= 100)");
        }
        this.ioRatio = ioRatio;
    }
    //重建NIO Selector对象
    public void rebuildSelector() {
    //只允许在EventLoop的线程中执行
        if (!inEventLoop()) {
            execute(new Runnable() {
                @Override
                public void run() {
                    rebuildSelector0();
                }
            });
            return;
        }
        rebuildSelector0();
    }

    @Override
    public int registeredChannels() {
        return selector.keys().size() - cancelledKeys;
    }
	//重建Selector对象
    private void rebuildSelector0() {
    //原来的Selector
        final Selector oldSelector = selector;
        final SelectorTuple newSelectorTuple;

        if (oldSelector == null) {
            return;
        }
		//创建新的Selector对象
        try {
            newSelectorTuple = openSelector();
        } catch (Exception e) {
            logger.warn("Failed to create a new Selector.", e);
            return;
        }
        //将注册到NioEventLoop上的所有Channel,注册到新创建Selector对象上
        //计算重新注册成功的Channel数量
        int nChannels = 0;
        for (SelectionKey key: oldSelector.keys()) {
            Object a = key.attachment();
            try {
                if (!key.isValid() || key.channel().keyFor(newSelectorTuple.unwrappedSelector) != null) {
                    continue;
                }
                int interestOps = key.interestOps();
                //取消老的SelectionKey
                key.cancel();
                //将Channel注册到新的Selector对象上
                SelectionKey newKey = key.channel().register(newSelectorTuple.unwrappedSelector, interestOps, a);
                //修改Channel的selectionKey指向新的SelectionKey上
                if (a instanceof AbstractNioChannel) {
                    ((AbstractNioChannel) a).selectionKey = newKey;
                }
                //计数++
                nChannels ++;
            } catch (Exception e) {
                logger.warn("Failed to re-register a Channel to the new Selector.", e);
                //关闭发生异常的Channel
                if (a instanceof AbstractNioChannel) {
                    AbstractNioChannel ch = (AbstractNioChannel) a;
                    ch.unsafe().close(ch.unsafe().voidPromise());
                    //调用NioTask的取消注册事件
                } else {
                    @SuppressWarnings("unchecked")
                    NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
                    invokeChannelUnregistered(task, key, e);
                }
            }
        }
		//修改selector和unwrappedSelector指向新的Selector对象
        selector = newSelectorTuple.selector;
        unwrappedSelector = newSelectorTuple.unwrappedSelector;
		//关闭老的Selector对象
        try {
            oldSelector.close();
        } catch (Throwable t) {
            if (logger.isWarnEnabled()) {
                logger.warn("Failed to close the old Selector.", t);
            }
        }

        if (logger.isInfoEnabled()) {
            logger.info("Migrated " + nChannels + " channel(s) to the new Selector.");
        }
    }
	//NioEventLoop运行,处理任务。
    @Override
    protected void run() {
        int selectCnt = 0;
        for (;;) {
            try {
                int strategy;
                try {
                //选择策略
                    strategy = selectStrategy.calculateStrategy(selectNowSupplier, hasTasks());
                    switch (strategy) {
                    //默认实现下,不存在这个情况
                    case SelectStrategy.CONTINUE:
                        continue;
					//NIO不支持
                    case SelectStrategy.BUSY_WAIT:
					//选择策略
                    case SelectStrategy.SELECT:
                        long curDeadlineNanos = nextScheduledTaskDeadlineNanos();
                        if (curDeadlineNanos == -1L) {
                            curDeadlineNanos = NONE; 
                        }
                        nextWakeupNanos.set(curDeadlineNanos);
                        try {
                            if (!hasTasks()) {
                                strategy = select(curDeadlineNanos);
                            }
                        } finally {
                            nextWakeupNanos.lazySet(AWAKE);
                        }
                    default:
                    }
                } catch (IOException e) {
                    rebuildSelector0();
                    selectCnt = 0;
                    handleLoopException(e);
                    continue;
                }

                selectCnt++;
                cancelledKeys = 0;
                needsToSelectAgain = false;
                final int ioRatio = this.ioRatio;
                boolean ranTasks;
                if (ioRatio == 100) {
                    try {
                        if (strategy > 0) {
                        //处理Channel感兴趣的就绪IO事件
                            processSelectedKeys();
                        }
                    } finally {
                        //运行所有普通任务和定时任务,不限制时间
                        ranTasks = runAllTasks();
                    }
                } else if (strategy > 0) {
                //得到开始时间
                    final long ioStartTime = System.nanoTime();
                    try {
                        processSelectedKeys();
                    } finally {
                        //运行所有普通任务和定时任务,限制时间
                        final long ioTime = System.nanoTime() - ioStartTime;
                        ranTasks = runAllTasks(ioTime * (100 - ioRatio) / ioRatio);
                    }
                } else {
                    ranTasks = runAllTasks(0); // This will run the minimum number of tasks
                }

                if (ranTasks || strategy > 0) {
                    if (selectCnt > MIN_PREMATURE_SELECTOR_RETURNS && logger.isDebugEnabled()) {
                        logger.debug("Selector.select() returned prematurely {} times in a row for Selector {}.",
                                selectCnt - 1, selector);
                    }
                    selectCnt = 0;
                } else if (unexpectedSelectorWakeup(selectCnt)) { // Unexpected wakeup (unusual case)
                    selectCnt = 0;
                }
            } catch (CancelledKeyException e) {
                // Harmless exception - log anyway
                if (logger.isDebugEnabled()) {
                    logger.debug(CancelledKeyException.class.getSimpleName() + " raised by a Selector {} - JDK bug?",
                            selector, e);
                }
            } catch (Throwable t) {
                handleLoopException(t);
            }
			//EventLoop优雅关闭
            try {
                if (isShuttingDown()) {
                    closeAll();
                    if (confirmShutdown()) {
                        return;
                    }
                }
            } catch (Throwable t) {
                handleLoopException(t);
            }
        }
    }


    private boolean unexpectedSelectorWakeup(int selectCnt) {
        if (Thread.interrupted()) {
            if (logger.isDebugEnabled()) {
                logger.debug("Selector.select() returned prematurely because " +
                        "Thread.currentThread().interrupt() was called. Use " +
                        "NioEventLoop.shutdownGracefully() to shutdown the NioEventLoop.");
            }
            return true;
        }
        if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 &&
                selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) {
            // The selector returned prematurely many times in a row.
            // Rebuild the selector to work around the problem.
            logger.warn("Selector.select() returned prematurely {} times in a row; rebuilding Selector {}.",
                    selectCnt, selector);
            rebuildSelector();
            return true;
        }
        return false;
    }
	//处理异常
    private static void handleLoopException(Throwable t) {
        logger.warn("Unexpected exception in the selector loop.", t);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
    }
//处理Channel新增就绪的IO事件
    private void processSelectedKeys() {
        if (selectedKeys != null) {
        //处理Channel新增就绪的IO事件
            processSelectedKeysOptimized();
        } else {
            processSelectedKeysPlain(selector.selectedKeys());
        }
    }

    @Override
    protected void cleanup() {
        try {
            selector.close();
        } catch (IOException e) {
            logger.warn("Failed to close a selector.", e);
        }
    }

    void cancel(SelectionKey key) {
        key.cancel();
        cancelledKeys ++;
        if (cancelledKeys >= CLEANUP_INTERVAL) {
            cancelledKeys = 0;
            needsToSelectAgain = true;
        }
    }
	//处理Channel新增就绪的IO事件
    private void processSelectedKeysPlain(Set<SelectionKey> selectedKeys) {
        if (selectedKeys.isEmpty()) {
            return;
        }
		//遍历SelectionKey迭代器
        Iterator<SelectionKey> i = selectedKeys.iterator();
        for (;;) {
        	//获得SelectionKey对象
            final SelectionKey k = i.next();
            final Object a = k.attachment();
            //从迭代器中移除
            i.remove();
			//处理一个Channel就绪的IO事件
            if (a instanceof AbstractNioChannel) {
                processSelectedKey(k, (AbstractNioChannel) a);
                //使用NioTask处理一个Channel就绪的IO事件
            } else {
                @SuppressWarnings("unchecked")
                NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
                processSelectedKey(k, task);
            }
			//没有下一个节点就结束
            if (!i.hasNext()) {
                break;
            }
			//是否需要再次筛选
            if (needsToSelectAgain) {
                selectAgain();
                selectedKeys = selector.selectedKeys();
                if (selectedKeys.isEmpty()) {
                    break;
                } else {
                    i = selectedKeys.iterator();
                }
            }
        }
    }

    private void processSelectedKeysOptimized() {
    //遍历数组
        for (int i = 0; i < selectedKeys.size; ++i) {
            final SelectionKey k = selectedKeys.keys[i];
            selectedKeys.keys[i] = null;
            final Object a = k.attachment();
			//处理一个Channel就绪IO事件
            if (a instanceof AbstractNioChannel) {
                processSelectedKey(k, (AbstractNioChannel) a);
            } else {
                @SuppressWarnings("unchecked")
                NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
                processSelectedKey(k, task);
            }

            if (needsToSelectAgain) {
                selectedKeys.reset(i + 1);

                selectAgain();
                i = -1;
            }
        }
    }
	//处理一个Channel就绪的IO事件
    private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {
        final AbstractNioChannel.NioUnsafe unsafe = ch.unsafe();
        //如果SelectionKey是不合法的则关闭Channel
        if (!k.isValid()) {
            final EventLoop eventLoop;
            try {
                eventLoop = ch.eventLoop();
            } catch (Throwable ignored) {
                return;
            }
            if (eventLoop == this) {
                unsafe.close(unsafe.voidPromise());
            }
            return;
        }

        try {
        //获得就绪的IO事件的ops
            int readyOps = k.readyOps();
            if ((readyOps & SelectionKey.OP_CONNECT) != 0) {
            //移除对OP_CONNECT感兴趣
                int ops = k.interestOps();
                ops &= ~SelectionKey.OP_CONNECT;
                k.interestOps(ops);
				//完成连接
                unsafe.finishConnect();
            }
            if ((readyOps & SelectionKey.OP_WRITE) != 0) {
            //向Channel写入数据
                ch.unsafe().forceFlush();
            }
            if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {
                unsafe.read();
            }
        } catch (CancelledKeyException ignored) {
        //发生异常关闭Channel
            unsafe.close(unsafe.voidPromise());
        }
    }
	//自定义实现Channel处理ChannelIO就绪事件
    private static void processSelectedKey(SelectionKey k, NioTask<SelectableChannel> task) {
        int state = 0;
        try {
        //调用NIOTask的Chanel就绪事件
            task.channelReady(k.channel(), k);
            state = 1;
        } catch (Exception e) {
        //SelectionKey取消
            k.cancel();
            //执行Channel取消注册
            invokeChannelUnregistered(task, k, e);
            state = 2;
        } finally {
            switch (state) {
            case 0:
                k.cancel();
                invokeChannelUnregistered(task, k, null);
                break;
            case 1:
            //SelelctionKey不合法,则执行Channel取消注册
                if (!k.isValid()) { // Cancelled by channelReady()
                    invokeChannelUnregistered(task, k, null);
                }
                break;
            }
        }
    }

    private void closeAll() {
        selectAgain();
        Set<SelectionKey> keys = selector.keys();
        Collection<AbstractNioChannel> channels = new ArrayList<AbstractNioChannel>(keys.size());
        for (SelectionKey k: keys) {
            Object a = k.attachment();
            if (a instanceof AbstractNioChannel) {
                channels.add((AbstractNioChannel) a);
            } else {
                k.cancel();
                @SuppressWarnings("unchecked")
                NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
                invokeChannelUnregistered(task, k, null);
            }
        }

        for (AbstractNioChannel ch: channels) {
            ch.unsafe().close(ch.unsafe().voidPromise());
        }
    }
	//执行Channel取消注册
    private static void invokeChannelUnregistered(NioTask<SelectableChannel> task, SelectionKey k, Throwable cause) {
        try {
            task.channelUnregistered(k.channel(), cause);
        } catch (Exception e) {
            logger.warn("Unexpected exception while running NioTask.channelUnregistered()", e);
        }
    }
	//唤醒线程
    @Override
    protected void wakeup(boolean inEventLoop) {
        if (!inEventLoop && nextWakeupNanos.getAndSet(AWAKE) != AWAKE) {
            selector.wakeup();
        }
    }

    @Override
    protected boolean beforeScheduledTaskSubmitted(long deadlineNanos) {
        return deadlineNanos < nextWakeupNanos.get();
    }

    @Override
    protected boolean afterScheduledTaskSubmitted(long deadlineNanos) {
        // Note this is also correct for the nextWakeupNanos == -1 (AWAKE) case
        return deadlineNanos < nextWakeupNanos.get();
    }

    Selector unwrappedSelector() {
        return unwrappedSelector;
    }
	//立刻选择
    int selectNow() throws IOException {
        return selector.selectNow();
    }
	//选择查询任务
    private int select(long deadlineNanos) throws IOException {
        if (deadlineNanos == NONE) {
            return selector.select();
        }
        //计算本次select的超时时间
        long timeoutMillis = deadlineToDelayNanos(deadlineNanos + 995000L) / 1000000L;
        //如果超时时间为负,就立刻选择
        return timeoutMillis <= 0 ? selector.selectNow() : selector.select(timeoutMillis);
    }

    private void selectAgain() {
        needsToSelectAgain = false;
        try {
            selector.selectNow();
        } catch (Throwable t) {
            logger.warn("Failed to update SelectionKeys.", t);
        }
    }
}
【Netty】Netty时间轮实践与源码解析 阅读详情

相关推荐

Netty源码解析-SizeClasses

引领完成Docker的安装、部署、管理和扩展,让其经历从测试到生产的整个开发生命周期,深入了解Docker适用于什么场景。并且这本Docker的学习权威指南介绍了其组件的基础知识,然后用Docker构建容器和服务来完成各种任务:利用Docker为新项目建立测试环境,演示如何使用持续集成的工作流集成Docker,如何构建应用程序服务和平台,如何使用Docker的API,如何扩展Docker。

2401_84023482的博客 1159

NioEventLoop解析

NioEventLoop解析

qq_40913932的博客 504

【Netty】netty启动流程源码解析

【Netty】netty启动流程源码解析

芝兰生于深谷,不以无人而不芳 1319

Netty 的主要组件

ByteBuf 组件 当我们进行数据传输的时候,往往需要使用到缓冲区,常用的缓冲区就是 JDK NIO类库 提供的 Buffer组件,7 种基本数据类型 ( Boolean 除外 ) 都有自己的缓冲区实现。对于 NIO编程 而言,我们主要使用的是 ByteBuffer。从功能角度而言,ByteBuffer 完全可以满足 NIO编程 的需 要,但是由于 NIO编程 的复杂性,ByteBuffer 也...

Nicholas.S的博客 709

串口调试神器诞生记:我是如何用Cursor+AI自动生成C#上位机的(含VSCode插件清单)

本文详细介绍了如何利用Cursor和AI技术快速开发C#上位机程序,实现高效的串口通讯调试。从开发环境搭建到代码自动生成,再到性能优化和功能增强,全面展示了AI辅助开发在串口调试中的实际应用和显著效率提升。

weixin_28340315的博客 302

clock-gating整理

文章目录clock gating 理解1、latch双稳态器件常见锁存器结构SR锁存器D锁存器2、clock gating(clock low-active) latch + AND gating 电路(clock high-active)latch + OR gating 电路 clock gating 理解 1、latch 参考:https://www.cnblogs.com/IClearner/p/6443539.html 双稳态器件 稳定状态为0或1两种 举例:交叉耦合反相器 假设初始Q为1,则可

d_b_的博客 1万+

吃透Netty源码系列三之bossGroup注册通道

Netty源码深度解析系列三向bossGroup里注册通道 向bossGroup里注册通道 我们接着上篇继续,接下去就是注册通道了ChannelFuture regFuture = config().group().register(channel);: @Override public ChannelFuture register(Channel channel) { ...

王伟王胖胖的博客 1841

BIM Revit教程(六)尝试安装 Revit 时显示“Autodesk Revit 已安装。”

在安装Revit或RevitLT时,若系统提示“AutodeskRevit版本已安装”,通常是由于旧版本残留文件未完全清除所致。解决方案包括:1.通过控制面板或Windows设置卸载旧版本Revit,确保所有相关组件被移除;2.使用Autodesk卸载工具(AdskUninstallHelper)进一步清理;3.谨慎操作注册表,删除与Revit相关的残留项;4.确保系统有至少30GB的可用磁盘空间;5.完成上述步骤后,重新尝试安装Revit。此外,文章还提到了一个免费功能商店,供用户寻找提效工具,并鼓励粉丝

ZOZO_888的博客 2129

Netty中NioEventLoop的两个逻辑点分析

1、NioEventLoop中如何优化java原生的Selector 在NioEventLoop的构造函数中,我们可以看到java原生的Selector并不是由SelectorProvider返回的,而是由内部的另外一个方法openSelector返回。 NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider, SelectStrat

TheOne的博客 439

共聚焦显微镜的光源、工作原理与选型

共聚焦显微镜作为科研与工业领域中重要的微观成像工具,凭借光源的精准适配性、光学切片技术的三维成像能力,以及对不同工业场景的定制化适配潜力,为半导体检测、工业部件分析、智能制造升级提供了关键技术支撑。深入理解其光源特性、工作原理与选型逻辑,能帮助工程师与技术人员精准匹配设备与生产需求,既保障微观检测的精度与效率,又为产业优化、技术创新筑牢微观观测的基础。

PhotonixBay的博客 1539

手把手教你用OpenCV+Python实现HALCON级模板匹配(附工业案例代码)

本文详细介绍了如何利用开源计算机视觉库OpenCV和Python,构建媲美HALCON商业软件的工业级模板匹配解决方案。通过分析工业检测的核心挑战,文章提供了从模板预处理、多策略融合匹配到应对尺度与旋转的完整代码实现,并附有连接器引脚检测的实战案例,为工业自动化场景下的高精度视觉检测提供了低成本、高可控性的技术路径。

e3f4g5的博客 284

DolphinScheduler 3.2.0 Worker启动核心源码解析

摘要:DolphinScheduler Worker启动流程包括多个关键步骤:1)启动Netty RPC服务端和客户端,实现任务接收与结果反馈;2)通过SPI加载任务插件,支持多种任务类型;3)注册到Zookeeper注册中心,使Master可发现;4)启动管理线程处理任务队列和执行;5)开启消息重试线程确保可靠性。Worker采用Netty异步通信、线程池任务执行、注册中心心跳检测等机制,实现了高并发、可靠性和可扩展性,完整支持"接收-执行-反馈"的任务处理闭环。(148字)

道可道非常道 1288

svn 分支(branch)和标签(tag)管理

svn的分支管理

caohongxing的博客 3万+

Netty 核心源码解析

Netty 第一讲:Netty 架构与原理本文是《Netty 三讲》的第二讲:Netty 核心源码解析(部分),大纲如下:前言1. Netty 服务端启动过程源码剖析1.1. 执行 ne...

weixin_41385912的博客 1万+

数据库课程案例——电力公司收费管理系统分析与实践,完整带SQL语句

某电力公司收费管理信息系统实现客户信息、用电类型(类别号、类别名、电价)及业务员管理;实现客户用电信息管理(客户号、月份、用电类别号、用电度数);实现客户费用管理(客户号、月份、费用、收费标志),收费标志的默认值为“未收”;实现收费登记(客户、月份、应收费用、实收费用、业务员),并自动修改收费标志(用触发器实现);创建触发器,实现收费时自动更加应收费用和实收费用,计算本次结余,然后修改客户信息表中的结余金额;创建存储过程统计指定月份应收费用和实收费用;创建存储过程查询指定月份未交费的用户信息,以便崔费;创建

qq_44242804的博客 2763

基于lstm+gru+transformer的电池寿命预测健康状态预测-完整数据代码

基于lstm+gru+transformer的电池寿命预测健康状态预测-完整数据代码

882

Netty源码解析-Netty源码包及IO模式源码分析

Netty通过channel的反射工厂获取channel的构造器,channel类型通过参数传递(这里实现对不同类型IO的支持),channel通过反射工厂在需要的时候构造出来(这里是一个优化)。我们可以看到Netty的代码确实做了很多优化。

qq_36037795的博客 2239

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Netty框架源码解析

Netty的线程模型

弦月的博客 1万+

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Netty——源码解析

JAVA后端开发知识总结(持续更新…) Netty—— 文章目录Netty——零、前言一、Netty服务器启动源码 零、前言 在 io.netty.example 包下,有很多 Netty 源码案例,可以用来分析。 一、Netty服务器启动源码 源码需要剖析到 Netty 中调用 doBind 方法,追踪到 NioServerSocketChannel 的 doBind。 同时要 Debug 程序到 NioEventLoop 类的 run 方法,无限循环,在服务器端运行。 ...

weixin_43415481的博客 1800

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Netty启动源码解析

Netty启动源码解析

qq_40913932的博客 1100

Netty源码深度解析

最后做一个小的总结,下图是我在网上,充分说明了Netty框架的运行模式,它是基于Reactor模型的主从架构:需要创建两个线程组EventLoopGroup,即bossGroup和workerGroup,一般bossGroup设置的线程组中线程的数量为1(也可以设置>1,如果这样设置的话,就需要绑定其他的端口,设置几个,绑定几个端口),workerGroup设置的线程组是多个,不设置默认创建的线程数量为 CPU核心数×2。今天,聊一聊Netty源码。因此,Netty使用。

weixin_41338970的博客 2281

Netty源码解析

Netty源码解析Netty源码解析示例NioEventLoopGroup的创建ServerBootstrap 创建和配置端口绑定,启动服务端NioServerSocketChannel的创建和初始化NioServerSocketChannel的创建NioServerSocketChannel的初始化端口绑定接收客户端连接请求,注册Channel到workGroup中Netty 接受请求过程ChannelPipeline,ChannelHandler,ChannelHandlerContext的创建Cha

weixin_43889578的博客 677

Netty 源码解析(上)

netty源码解析

黄裳博客 3413

Netty系列之源码解析(一)

今天是猿灯塔“365篇原创计划”第十三篇。 接下来的时间灯塔君持续更新Netty系列一共九篇 当前:Netty 源码解析(一)开始 Netty 源码解析(二): Netty 的 Channel Netty 源码解析(三): Netty 的 Future 和 Promise Netty 源码解析(四): Netty 的 ChannelPipeline Netty 源码解析(五): Netty 的线程...

猿灯塔的博客 660

Spring与Netty底层源码解析

本文介绍了Spring与Netty的整合以及对Netty底层源码的深入解析,在实际项目中,充分利用Spring提供的整合支持,结合对Netty底层源码的理解,可以更好地开发高性能、灵活的网络 应用,我们希望通过本文的介绍能够为大家在网络应用开发中提供一些参考,另外也希望通过阅读Netty的源码,能够对大家的技术水平有所帮助。

dzend的专栏 891

Netty 源码解析 ——— Netty 优雅关闭流程

本文是Netty文集中“Netty 源码解析”系列的文章。主要对Netty的重要流程以及类进行源码解析,以使得我们更好的去使用Netty。Netty是一个非常优秀的网络框架,对其源码解读的过程也是不断学习的过程。

yygr的博客 509
上一篇: Netty组件源码解析(2)
下一篇: Netty组件源码解析(4)
jacobbbbbbbb
博客等级 码龄7年 6粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值