This article will take a closer look at its member, EventLoop.

Class structure

NioEventLoop
SingleThreadEventLoop
SingleThreadEventLoop
SingleThreadEventExecutor
SingleThreadEventExecutor
Netty
NioEventLoop

SingleThreadEventExecutor

You can see from the name, SingleThreadEventExecutor is a single-threaded event actuators. The main things to do are thread management and event execution.

Thread management

In SingleThreadEventExecutor defines five thread state:

Private static final int ST_NOT_STARTED = 1; private static final int ST_NOT_STARTED = 1; / / private static final int ST_STARTED = 2; Private static final int ST_SHUTTING_DOWN = 3; Private static final int ST_SHUTDOWN = 4; /** * terminated */ private static final int ST_TERMINATED = 5;Copy the code

The corresponding methods are startThread, ShutdownExceptionexception, and Shutdown.

startThread

    private void startThread() {
        if (state == ST_NOT_STARTED) {
            if (STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED)) {
                try {
                    doStartThread(); } catch (Throwable cause) { STATE_UPDATER.set(this, ST_NOT_STARTED); PlatformDependent.throwException(cause); }}}}Copy the code

Before the startThread thread starts, an attempt is made to update the thread state to start. If the update succeeds, the doStartThread method is called to start the thread. This is where the subclass run method is called, such as the NioEventLoop that follows.

shutdownGracefully

public Future<? > shutdownGracefully(Long quietPeriod, Long Timeout, TimeUnit Unit) {// The waiting time needs to be greater than =0if (quietPeriod < 0) {
            throw new IllegalArgumentException("quietPeriod: " + quietPeriod + " (expected >= 0)"); } // The timeout period cannot be shorter than the idle timeif (timeout < quietPeriod) {
            throw new IllegalArgumentException(
                    "timeout: " + timeout + " (expected >= quietPeriod (" + quietPeriod + ")"); } // The time unit must be setif (unit == null) {
            throw new NullPointerException("unit"); } // Close directly to return to terminate the Futureif (isShuttingDown()) {
            return terminationFuture();
        }
        boolean inEventLoop = inEventLoop();
        boolean wakeup;
        int oldState;
        for(; ;) {// Close directly returns the termination of the Futureif (isShuttingDown()) {
                return terminationFuture();
            }
            int newState;
            wakeup = true;
            oldState = state;
            if (inEventLoop) {
                newState = ST_SHUTTING_DOWN;
            } else {
                switch (oldState) {
                    case ST_NOT_STARTED:
                    case ST_STARTED:
                        newState = ST_SHUTTING_DOWN;
                        break;
                    default:
                        newState = oldState;
                        wakeup = false; }}if (STATE_UPDATER.compareAndSet(this, oldState, newState)) {
                break;
            }
        }
        gracefulShutdownQuietPeriod = unit.toNanos(quietPeriod);
        gracefulShutdownTimeout = unit.toNanos(timeout);
        if (oldState == ST_NOT_STARTED) {
            try {
                doStartThread();
            } catch (Throwable cause) {
                STATE_UPDATER.set(this, ST_TERMINATED);
                terminationFuture.tryFailure(cause);

                if(! (cause instanceof Exception)) { PlatformDependent.throwException(cause); }returnterminationFuture; }}if (wakeup) {
            wakeup(inEventLoop);
        }

        return terminationFuture();
    }
Copy the code

The purpose of A Message is to allow the task that is being performed to run a little longer, while denying the new task. QuietPeriod and timeout are used in the confirmShutdown method, and of course have been converted to nanoseconds.

Event execution

   public void execute(Runnable task) {
        if (task == null) {
            throw new NullPointerException("task");
        }
        boolean inEventLoop = inEventLoop();
        if (inEventLoop) {
            addTask(task);
        } else {
            startThread();
            addTask(task);
            if(isShutdown() && removeTask(task)) { reject(); }}if(! addTaskWakesUp && wakesUpForTask(task)) { wakeup(inEventLoop); }}Copy the code

NioEventLoop

The core operations of NioEventLoop are in its run method:

    protected void run() {
        for(; ;) { try { switch (selectStrategy.calculateStrategy(selectNowSupplier, hasTasks())) {case SelectStrategy.CONTINUE:
                        continue;
                    caseSelectstrategy. SELECT: // reset wakenUp tofalseAnd select task select(wakenup.getandSet (false));
                        if (wakenUp.get()) {
                            selector.wakeup();
                        }
                    default:
                }
                cancelledKeys = 0;
                needsToSelectAgain = false; final int ioRatio = this.ioRatio; // When the processing time ratio of IO is 100%if(ioRatio == 100) { try { processSelectedKeys(); } finally { runAllTasks(); }}else{ final long ioStartTime = System.nanoTime(); try { processSelectedKeys(); } finally { final long ioTime = System.nanoTime() - ioStartTime; runAllTasks(ioTime * (100 - ioRatio) / ioRatio); }} catch (Throwable t) {// handleLoopException handleLoopException(t); } try {// In closed stateif (isShuttingDown()) {
                    // 关闭所有
                    closeAll();
                    if (confirmShutdown()) {
                        return; }} catch (Throwable t) {// handleLoopException handleLoopException(t); }}}Copy the code

This approach deals primarily with process control, including selection, processing, and closing.

The code comments in the post are all in: KAMIJYOUDOUMA, interested children’s shoes can follow.


This is the end of this article, if you feel that there is a harvest after reading, welcome to like, follow, add the public account [level 2 natural disaster], see more wonderful history!!