Hatena::¥Ö¥í¥°(Diary)

CLOVER

2017-09-30

Undertow ¤ ÇHttpHandler ¤ ò¼Â ¹ Ô ¤ ¹ ¤ ë ¥ ¹ ¥ ì ¥ à ¥ É ¤ òÀÚ ¤ êÂØ ¤ ¨ ¤ ë

Undertow¡Ä ¤ È ¤ ¤ ¤ ¦ ¤ «XNIO ¤ Ç ¤ Ï¡ ¢ 2¼ïÎà ¤ Î ¥ ¹ ¥ ì ¥ à ¥ É ¤ zu ¤ ¢ ¤ ê ¤ Þ ¤ ¹ ¡£

IO Thread ¤ È¡ ¢ ¥ Ö ¥ í ¥ à ¥ ¥ ó ¥ ° ¤ Ê ¥ und ¥ ¹ ¥ ¯ ¤ Ë »ÈÍÑ ¤ ¹ ¤ ë ¤ ³ ¤ È ¤ zu ¤ Ç ¤ ¤ ëWorker Thread ¤ Ç ¤ ¹ ¡£

Management of IO and Worker threads

XNIO workers

¢ ¨XNIO ¤ Î ¥ É ¥ ¥ å ¥ á ¥ ó ¥ È¡ ¢ ¤ ¢ ¤ ó ¤ Þ ¤ ê½ñ ¤ «¤ ì ¤ Æ ¤ Ê ¤ ¤ ¤ Ç ¤ ¹ ¤ Í ¤ §¡Ä

IO Thread ¤ Ï¡ ¢ ¥ Î ¥ ó ¥ Ö ¥ í ¥ à ¥ ¥ ó ¥ ° ¤ Ê ¥ und ¥ ¹ ¥ ¯ ¤ ò¼Â ¹ Ô ¤ ¹ ¤ ë ¤ und ¤ á ¤ Î ¥ ¹ ¥ ì ¥ à ¥ É ¤ Ç¡ ¢ ¥ Ö ¥ í ¥ à ¥ ¯ ¤ ¹ ¤ ë ¤ è ¤ ¦ ¤ ʽèÍý ¤ ò ¤ · ¤ Æ ¤ Ï ¤ ¤ ¤ ± ¤ Þ ¤ »¤ ó¡Ê¾ ¤ ÎÀܳ ¤ Ø ¤ νèÍý ¤ zu» ß ¤ Þ ¤ ë²ÄǽÀ ¤ zu ¤ ¢ ¤ ê ¤ Þ ¤ ¹ ¡Ë¡£
CPU ¥ ³ ¥ ¢ ¤ ¢ ¤ und ¤ ê¡ ¢ 2 ¤ Ä ¤ Î ¥ ¹ ¥ ì ¥ à ¥ É ¤ ¬Å¬ÀÚ ¤ Ê ¥ Ç ¥ Õ ¥ © ¥ ë ¥ ÈÃÍ ¤ Î ¤ è ¤ ¦ ¤ Ç ¤ ¹ ¤ ¬¡Ä¡ ©

Worker Thread ¤ Ï¡ ¢ ¥ Ö ¥ í ¥ à ¥ ¥ ó ¥ ° ¤ Ê ¥ und ¥ ¹ ¥ ¯ÍÑ ¤ Î ¥ ¹ ¥ ì ¥ à ¥ É ¥ ס¼ ¥ ë ¤ Ç´ÉÍý ¤ µ ¤ ì ¤ Þ ¤ ¹ ¡£°ìÈÌ ¤ Ë¡ ¢ CPU ¥ ³ ¥ ¢ ¿ô ¤ ¢ ¤ und ¤ ê10 ¥ ¹ ¥ ì ¥ à ¥ É ¤ ǽ½Ê¬ ¹ â ¤ ¤ ¤ Ï ¤ º¡ ¢
¤ È ¤ ¤ ¤ ¦ ´ ¶ ¤ ¸ ¤ Î ¥ É ¥ ¥ å ¥ á ¥ ó ¥ È ¤ Ë ¤ Ê ¤ Ã ¤ Æ ¤ ¤ ¤ Þ ¤ ¹ ¡£

¤ Ê ¤ ª¡ ¢ Undertow ¤ Î ¥ ³¡¼ ¥ É ¤ ò ¸«¤ ë ¤ È¡ ¢ ¤ der l ¤ ì ¤ ¾ ¤ ì ¤ Î ¥ ¹ ¥ ì ¥ à ¥ É ¤ Î ¥ Ç ¥ Õ ¥ © ¥ ë ¥ È¿ô ¤ ÏIO Thread ¤ ¬CPU ¥ ³ ¥ ¢ ¿ô or 2 ¤ ÎÂç ¤ ¤ ¤ Êý¡ ¢
Worker Thread ¤ ¬IO Thread¡ß8 ¤ Ç ¤ ¹ ¡£
https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/Undertow.java#L414-L415

¤ Ç¡ ¢ ¥ É ¥ ¥ å ¥ á ¥ ó ¥ È ¤ ËIO Thread ¤ «¤ éWorker Thread ¤ ËÀÚ ¤ êÂØ ¤ ¨ ¤ ëÊýË¡ ¤ ¬½ñ ¤ ¤ ¤ Æ ¤ ¢ ¤ ê ¤ Þ ¤ ¹ ¡£

Request Lifecycle

Undertow Request Lifecyle

HttpServerExchange#exchange ¤ ò »È ¤ ¤ ¤ Ê ¤ µ ¤ ¤ ¡ ¢ ¤ È¡£

º£²ó¡ ¢ ¤ ³ ¤ ì ¤ ò »î ¤ · ¤ Æ ¤ ß ¤ Þ ¤ · ¤ ç ¤ ¦ ¡£

½àÈ÷

¤ Þ ¤ º ¤ Ï¡ ¢ Maven°Í ¸´Ø ·¸ ¤ «¤ é¡£

        <dependency>
            <groupId>io.undertow</groupId>
            <artifactId>undertow-core</artifactId>
            <version>1.4.20.Final</version>
        </dependency>

´ Êñ ¤ ʵ¯Æ° ¥ ¯ ¥ é ¥ ¹ ¤ òºîÀ® ¤ · ¤ Þ ¤ ¹ ¡£
src/main/java/org/littlewings/undertow/App.java

package org.littlewings.undertow;

import io.undertow.Undertow;

public class App {
    public static void main(String... args) {
        Undertow undertow =
                Undertow
                        .builder()
                        .addHttpListener(8080, "localhost")
                        .setHandler(/** HttpHandler¤òÀßÄꤹ¤ë **/)
                        .build();

        undertow.start();

        System.console().readLine("> Enter, stop.");

        undertow.stop();
    }
}

¤ ³ ¤ ÎBuilder#setHandler ¤ ËÀßÄê ¤ ¹ ¤ ëHandler ¤ ò¡ ¢ ¤ Á ¤ ç ¤ à ¤ È ¤ º ¤ ÄÊÑ ¤ ¨ ¤ Ê ¤ zu ¤ é ¸«¤ Æ ¤ ¤ ¤ à ¤ Æ ¤ ß ¤ Þ ¤ · ¤ ç ¤ ¦ ¡£

                        .setHandler(/** HttpHandler¤òÀßÄꤹ¤ë **/)

ñ½ã ¤ Ê ¥ µ ¥ ó ¥ × ¥ ë

¤ È ¤ ê ¤ ¢ ¤ ¨ ¤ º¡ ¢ Æ° ¤ «¤ ¹ ¤ und ¤ á ¤ δÊñ ¤ Ê ¥ µ ¥ ó ¥ × ¥ ë ¤ ò½ñ ¤ ¤ ¤ Æ ¤ ß ¤ Þ ¤ ¹ ¡£
src/main/java/org/littlewings/undertow/SimpleHttpHandler.java

package org.littlewings.undertow;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import org.jboss.logging.Logger;

public class SimpleHttpHandler implements HttpHandler {
    Logger logger = Logger.getLogger(getClass());

    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {
        logger.infof(
                "%s [%s/%s] access, is io-thread? %b, is blocking? %b",
                LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE),
                Thread.currentThread().getName(),
                Thread.currentThread().getClass().getName(),
                exchange.isInIoThread(),
                exchange.isBlocking());

        exchange
                .getResponseSender()
                .send(
                        String.format(
                                "Response from: %s/%s, is io-thread? %b, is blocking? %b%n",
                                Thread.currentThread().getName(),
                                Thread.currentThread().getClass().getName(),
                                exchange.isInIoThread(),
                                exchange.isBlocking()
                        ));
    }
}

¥ ¹ ¥ ì ¥ à ¥ É̾ ¤ ä ¥ ¯ ¥ é ¥ ¹ ¡ ¢ ¸½ºß ¤ ¬IO Thread ¤ «¤ É ¤ ¦ ¤« ¡ © ¥ Ö ¥ í ¥ à ¥ ¥ ó ¥ ° ¤ · ¤ Æ ¤ ¤ ¤ ë ¤ «¤ É ¤ ¦ ¤« ¡ © ¤ òÊÖ ¤ ¹ ¤ è ¤ ¦ ¤ Ë ¤ · ¤ Æ ¤ ß ¤ Þ ¤ · ¤ ¿¡£

¤ ³ ¤ ì ¤ òÀßÄê ¤ · ¤ Æ

                        .setHandler(new SimpleHttpHandler())

³Îǧ¡£

$ curl http://localhost:8080
Response from: XNIO-1 I/O-1/org.xnio.nio.WorkerThread, is io-thread? true, is blocking? false
$ curl http://localhost:8080
Response from: XNIO-1 I/O-2/org.xnio.nio.WorkerThread, is io-thread? true, is blocking? false
$ curl http://localhost:8080
Response from: XNIO-1 I/O-3/org.xnio.nio.WorkerThread, is io-thread? true, is blocking? false
$ curl http://localhost:8080
Response from: XNIO-1 I/O-4/org.xnio.nio.WorkerThread, is io-thread? true, is blocking? false

HttpServerExchange#isInIoThread ¤ ¬true ¤ òÊÖ ¤ ¹ ¤ Î ¤ Ç¡ ¢ IO Thread ¤ ÇÆ°ºî ¤ · ¤ Æ ¤ ¤ ¤ ë ¤ è ¤ ¦ ¤ Ç ¤ ¹ ¡£

¤ È ¤ ê ¤ ¢ ¤ ¨ ¤ º¡ ¢ ¤ ï ¤ à ¤ È ¥ ¢ ¥ ¯ ¥ »¥ ¹ ¤ · ¤ Æ ¤ ß ¤ Æ

$ for i in `seq 200`; do curl http://localhost:8080; done

¥ ¹ ¥ ì ¥ à ¥ É ¥ À ¥ ó ¥ × ¤ ò ¸«¤ ë ¤ È¡ ¢ XNIO ¤ ÎIO Thread ¤ · ¤« ¤ ¤ ¤ Ê ¤ ¤ ¤ è ¤ ¦ ¤ Ç ¤ ¹ ¡£

$ jstack [PID] | grep XNIO
"XNIO-1 Accept" #20 prio=5 os_prio=0 tid=0x00007f567c53e000 nid=0x2d5b runnable [0x00007f56579f8000]
"XNIO-1 I/O-8" #19 prio=5 os_prio=0 tid=0x00007f567c53c800 nid=0x2d5a runnable [0x00007f5657af9000]
"XNIO-1 I/O-7" #18 prio=5 os_prio=0 tid=0x00007f567c53b000 nid=0x2d59 runnable [0x00007f5657bfa000]
"XNIO-1 I/O-6" #17 prio=5 os_prio=0 tid=0x00007f567c539000 nid=0x2d58 runnable [0x00007f5657cfb000]
"XNIO-1 I/O-5" #16 prio=5 os_prio=0 tid=0x00007f567c537800 nid=0x2d57 runnable [0x00007f5657dfc000]
"XNIO-1 I/O-4" #15 prio=5 os_prio=0 tid=0x00007f567c535800 nid=0x2d56 runnable [0x00007f5657efd000]
"XNIO-1 I/O-3" #14 prio=5 os_prio=0 tid=0x00007f567c534000 nid=0x2d55 runnable [0x00007f5657ffe000]
"XNIO-1 I/O-2" #13 prio=5 os_prio=0 tid=0x00007f567c532000 nid=0x2d54 runnable [0x00007f5664192000]
"XNIO-1 I/O-1" #12 prio=5 os_prio=0 tid=0x00007f567c530800 nid=0x2d53 runnable [0x00007f5664293000]

¤ Ê ¤ ë ¤ Û ¤ É¡ ©

IO Thread ¤ «¤ éWorker Thread ¤ ËÀÚ ¤ êÂØ ¤ ¨ ¤ ë

¤ Ç ¤ Ï¡ ¢ IO Thread ¤ «¤ éWorker Thread ¤ ËÀÚ ¤ êÂØ ¤ ¨ ¤ Æ ¤ ß ¤ Þ ¤ · ¤ ç ¤ ¦ ¡£
src/main/java/org/littlewings/undertow/DispatchWorkerHttpHandler.java

package org.littlewings.undertow;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import org.jboss.logging.Logger;

public class DispatchWorkerHttpHandler implements HttpHandler {
    Logger logger = Logger.getLogger(getClass());

    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {
        logger.infof(
                "%s [%s/%s] access, is io-thread? %b, is blocking? %b",
                LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE),
                Thread.currentThread().getName(),
                Thread.currentThread().getClass().getName(),
                exchange.isInIoThread(),
                exchange.isBlocking());

        if (exchange.isInIoThread()) {
            exchange.dispatch(this);
            logger.infof("return, dispatch to worker");
            return;
        }

        exchange
                .getResponseSender()
                .send(
                        String.format(
                                "Response from: %s/%s, is io-thread? %b, is blocking? %b%n",
                                Thread.currentThread().getName(),
                                Thread.currentThread().getClass().getName(),
                                exchange.isInIoThread(),
                                exchange.isBlocking()
                        ));
    }
}

¤ ³ ¤ ³ ¤ Ç ¤ Î ¥ Ý ¥ ¤ ¥ ó ¥ È ¤ Ï¡ ¢ HttpServerExchange#isInIoThread ¤ ¬true ¤ Î¾ì ¹ ç¡ ¢ HttpServerExchange#dispatch ¤ ÇHttpHandler ¤ òÅÏ ¤ · ¤ ÆÀÞ ¤ êÊÖ ¤ ¹ ¤ ³ ¤ È ¤ Ç ¤ ¹ ¤ Í¡£

        if (exchange.isInIoThread()) {
            exchange.dispatch(this);
            logger.infof("return, dispatch to worker");
            return;
        }

ÅÏ ¤ · ¤ Æ ¤ ¤ ¤ ë ¤ Î ¤ ¬this ¤ Ê ¤ Î ¤ Ç¡ ¢ ¤ ³ ¤ ÎHttpHandler ¤ ¬Worker Thread ¤ ǽèÍý ¤ µ ¤ ì ¤ ë ¤ è ¤ ¦ ¤ Ë ¤ Ê ¤ ê ¤ Þ ¤ ¹ ¡£

¤ ³ ¤ Á ¤ é ¤ ÎHttpHandler ¤ ò »ÈÍÑ ¤ ¹ ¤ ë ¤ è ¤ ¦ ¤ Ë¡ ¢ App ¥ ¯ ¥ é ¥ ¹ ¤ ò½ ¤ Àµ ¤ · ¤ Þ ¤ ¹ ¡£

                        .setHandler(new DispatchWorkerHttpHandler())

³Îǧ ¤ · ¤ Æ ¤ ß ¤ Þ ¤ · ¤ ç ¤ ¦ ¡£

$ curl http://localhost:8080
Response from: XNIO-1 task-5/java.lang.Thread, is io-thread? false, is blocking? false

¤ ³ ¤ Î »þ¡ ¢ HttpHandler ¦ ¤ Ë ¤ ÏhandleRequest ¤ ÎÀèƬ ¤ Î ¥ í ¥ ° ¤ ¬2²ó½ÐÎÏ ¤ µ ¤ ì ¤ ë ¤ ³ ¤ È ¤ Ë ¤ Ê ¤ ê ¤ Þ ¤ ¹ ¡£

9 30, 2017 12:16:53 ¸á¸å org.littlewings.undertow.DispatchWorkerHttpHandler handleRequest
INFO: return, dispatch to worker
9 30, 2017 12:16:53 ¸á¸å org.littlewings.undertow.DispatchWorkerHttpHandler handleRequest
INFO: 20170930 [XNIO-1 task-5/java.lang.Thread] access, is io-thread? false, is blocking? false

HttpServerExchange#isInIoThread ¤ ¬false ¤ Ë ¤ Ê ¤ ê¡ ¢ ½Ð ¤ Æ ¤ ¯ ¤ ë ¥ ¹ ¥ ì ¥ à ¥ É̾ ¤ âÊÑ ¤ ï ¤ ê ¤ Þ ¤ · ¤ und ¤ Í¡£

¤ Þ ¤ ¿¡ ¢ ¤ ¶ ¤ à ¤ È ¥ ¢ ¥ ¯ ¥ »¥ ¹ ¤ · ¤ Æ ¤ ß ¤ Þ ¤ ¹ ¡£

$ for i in `seq 200`; do curl http://localhost:8080; done

¥ ¹ ¥ ì ¥ à ¥ É ¥ À ¥ ó ¥ × ¤ ò ¸«¤ Æ ¤ ß ¤ ë ¤ È¡ ¢ ÂçÎÌ ¤ Î ¥ ¹ ¥ ì ¥ à ¥ É ¤ ¬½Ð¸½ ¤ · ¤ Þ ¤ ¹ ¡£

$ jstack [PID] | grep XNIO
"XNIO-1 task-64" #85 prio=5 os_prio=0 tid=0x00007f211c011800 nid=0x3287 waiting on condition [0x00007f216cdcc000]
"XNIO-1 task-63" #84 prio=5 os_prio=0 tid=0x00007f20f8048000 nid=0x3284 waiting on condition [0x00007f216cecd000]
"XNIO-1 task-62" #83 prio=5 os_prio=0 tid=0x00007f2104011000 nid=0x3281 waiting on condition [0x00007f216cfce000]
"XNIO-1 task-61" #82 prio=5 os_prio=0 tid=0x00007f2100011800 nid=0x327e waiting on condition [0x00007f216d0cf000]
"XNIO-1 task-60" #81 prio=5 os_prio=0 tid=0x00007f210c011000 nid=0x327b waiting on condition [0x00007f216d1d0000]
"XNIO-1 task-59" #80 prio=5 os_prio=0 tid=0x00007f2108011800 nid=0x3278 waiting on condition [0x00007f216d2d1000]
"XNIO-1 task-58" #79 prio=5 os_prio=0 tid=0x00007f2114011000 nid=0x3275 waiting on condition [0x00007f216d3d2000]
"XNIO-1 task-57" #78 prio=5 os_prio=0 tid=0x00007f211000f800 nid=0x3272 waiting on condition [0x00007f216d4d3000]
"XNIO-1 task-56" #77 prio=5 os_prio=0 tid=0x00007f211c00f800 nid=0x326f waiting on condition [0x00007f216d5d4000]
"XNIO-1 task-55" #76 prio=5 os_prio=0 tid=0x00007f20f8046800 nid=0x326c waiting on condition [0x00007f216d6d5000]
"XNIO-1 task-54" #75 prio=5 os_prio=0 tid=0x00007f210400f800 nid=0x3269 waiting on condition [0x00007f216d7d6000]
"XNIO-1 task-53" #74 prio=5 os_prio=0 tid=0x00007f210000f800 nid=0x3266 waiting on condition [0x00007f216d8d7000]
"XNIO-1 task-52" #73 prio=5 os_prio=0 tid=0x00007f210c00f800 nid=0x3263 waiting on condition [0x00007f216d9d8000]
"XNIO-1 task-51" #72 prio=5 os_prio=0 tid=0x00007f210800f800 nid=0x3260 waiting on condition [0x00007f216dad9000]
"XNIO-1 task-50" #71 prio=5 os_prio=0 tid=0x00007f211400f800 nid=0x325d waiting on condition [0x00007f216dbda000]
"XNIO-1 task-49" #70 prio=5 os_prio=0 tid=0x00007f211000e000 nid=0x325a waiting on condition [0x00007f216dcdb000]
"XNIO-1 task-48" #69 prio=5 os_prio=0 tid=0x00007f211c00e000 nid=0x3257 waiting on condition [0x00007f216dddc000]
"XNIO-1 task-47" #68 prio=5 os_prio=0 tid=0x00007f20f8044800 nid=0x3254 waiting on condition [0x00007f216dedd000]
"XNIO-1 task-46" #67 prio=5 os_prio=0 tid=0x00007f210400d800 nid=0x3251 waiting on condition [0x00007f216dfde000]
"XNIO-1 task-45" #66 prio=5 os_prio=0 tid=0x00007f210000e000 nid=0x324e waiting on condition [0x00007f216e0df000]
"XNIO-1 task-44" #65 prio=5 os_prio=0 tid=0x00007f210c00d800 nid=0x324b waiting on condition [0x00007f216e1e0000]
"XNIO-1 task-43" #64 prio=5 os_prio=0 tid=0x00007f210800e000 nid=0x3248 waiting on condition [0x00007f216e2e1000]
"XNIO-1 task-42" #63 prio=5 os_prio=0 tid=0x00007f211400d800 nid=0x3245 waiting on condition [0x00007f216e3e2000]
"XNIO-1 task-41" #62 prio=5 os_prio=0 tid=0x00007f211000c000 nid=0x3242 waiting on condition [0x00007f216e4e3000]
"XNIO-1 task-40" #61 prio=5 os_prio=0 tid=0x00007f211c00c000 nid=0x323f waiting on condition [0x00007f216e5e4000]
"XNIO-1 task-39" #60 prio=5 os_prio=0 tid=0x00007f20f803d800 nid=0x323c waiting on condition [0x00007f216e6e5000]
"XNIO-1 task-38" #59 prio=5 os_prio=0 tid=0x00007f210400c000 nid=0x3239 waiting on condition [0x00007f216e7e6000]
"XNIO-1 task-37" #58 prio=5 os_prio=0 tid=0x00007f210000c000 nid=0x3236 waiting on condition [0x00007f216e8e7000]
"XNIO-1 task-36" #57 prio=5 os_prio=0 tid=0x00007f210c00c000 nid=0x3233 waiting on condition [0x00007f216e9e8000]
"XNIO-1 task-35" #56 prio=5 os_prio=0 tid=0x00007f210800c000 nid=0x3230 waiting on condition [0x00007f216eae9000]
"XNIO-1 task-34" #55 prio=5 os_prio=0 tid=0x00007f211400c000 nid=0x322c waiting on condition [0x00007f216ebea000]
"XNIO-1 task-33" #54 prio=5 os_prio=0 tid=0x00007f211000a800 nid=0x3229 waiting on condition [0x00007f216eceb000]
"XNIO-1 task-32" #53 prio=5 os_prio=0 tid=0x00007f211c00a800 nid=0x3226 waiting on condition [0x00007f216edec000]
"XNIO-1 task-31" #52 prio=5 os_prio=0 tid=0x00007f20f803c000 nid=0x3223 waiting on condition [0x00007f216eeed000]
"XNIO-1 task-30" #51 prio=5 os_prio=0 tid=0x00007f210400a000 nid=0x3220 waiting on condition [0x00007f216efee000]
"XNIO-1 task-29" #50 prio=5 os_prio=0 tid=0x00007f210000a800 nid=0x321d waiting on condition [0x00007f216f0ef000]
"XNIO-1 task-28" #49 prio=5 os_prio=0 tid=0x00007f210c00a000 nid=0x321a waiting on condition [0x00007f216f1f0000]
"XNIO-1 task-27" #48 prio=5 os_prio=0 tid=0x00007f210800a800 nid=0x3217 waiting on condition [0x00007f216f2f1000]
"XNIO-1 task-26" #47 prio=5 os_prio=0 tid=0x00007f211400a000 nid=0x3214 waiting on condition [0x00007f216f3f2000]
"XNIO-1 task-25" #46 prio=5 os_prio=0 tid=0x00007f2110008800 nid=0x3211 waiting on condition [0x00007f216f4f3000]
"XNIO-1 task-24" #45 prio=5 os_prio=0 tid=0x00007f211c008800 nid=0x320e waiting on condition [0x00007f216f5f4000]
"XNIO-1 task-23" #44 prio=5 os_prio=0 tid=0x00007f20f803a000 nid=0x320b waiting on condition [0x00007f216f6f5000]
"XNIO-1 task-22" #43 prio=5 os_prio=0 tid=0x00007f2104008800 nid=0x3208 waiting on condition [0x00007f216f7f6000]
"XNIO-1 task-21" #42 prio=5 os_prio=0 tid=0x00007f2100008800 nid=0x3205 waiting on condition [0x00007f216f8f7000]
"XNIO-1 task-20" #41 prio=5 os_prio=0 tid=0x00007f210c008800 nid=0x3202 waiting on condition [0x00007f216f9f8000]
"XNIO-1 task-19" #40 prio=5 os_prio=0 tid=0x00007f2108008800 nid=0x31ff waiting on condition [0x00007f216faf9000]
"XNIO-1 task-18" #39 prio=5 os_prio=0 tid=0x00007f2114008800 nid=0x31fc waiting on condition [0x00007f216fbfa000]
"XNIO-1 task-17" #38 prio=5 os_prio=0 tid=0x00007f2110007000 nid=0x31f9 waiting on condition [0x00007f216fcfb000]
"XNIO-1 task-16" #37 prio=5 os_prio=0 tid=0x00007f211c007000 nid=0x31f6 waiting on condition [0x00007f216fdfc000]
"XNIO-1 task-15" #36 prio=5 os_prio=0 tid=0x00007f20f8038800 nid=0x31f3 waiting on condition [0x00007f216fefd000]
"XNIO-1 task-14" #35 prio=5 os_prio=0 tid=0x00007f2104007000 nid=0x31f0 waiting on condition [0x00007f216fffe000]
"XNIO-1 task-13" #34 prio=5 os_prio=0 tid=0x00007f2100007000 nid=0x31ed waiting on condition [0x00007f21741cb000]
"XNIO-1 task-12" #33 prio=5 os_prio=0 tid=0x00007f210c007000 nid=0x31ea waiting on condition [0x00007f21742cc000]
"XNIO-1 task-11" #32 prio=5 os_prio=0 tid=0x00007f2108007000 nid=0x31e7 waiting on condition [0x00007f21743cd000]
"XNIO-1 task-10" #31 prio=5 os_prio=0 tid=0x00007f2114007000 nid=0x31e4 waiting on condition [0x00007f21744ce000]
"XNIO-1 task-9" #30 prio=5 os_prio=0 tid=0x00007f2110005000 nid=0x31e1 waiting on condition [0x00007f21745cf000]
"XNIO-1 task-8" #29 prio=5 os_prio=0 tid=0x00007f211c005800 nid=0x31de waiting on condition [0x00007f21746d0000]
"XNIO-1 task-7" #28 prio=5 os_prio=0 tid=0x00007f20f8037000 nid=0x31db waiting on condition [0x00007f21747d1000]
"XNIO-1 task-6" #27 prio=5 os_prio=0 tid=0x00007f2104005000 nid=0x31d8 waiting on condition [0x00007f21748d2000]
"XNIO-1 task-5" #26 prio=5 os_prio=0 tid=0x00007f2100005000 nid=0x31d5 waiting on condition [0x00007f21749d3000]
"XNIO-1 task-4" #25 prio=5 os_prio=0 tid=0x00007f210c005000 nid=0x31d2 waiting on condition [0x00007f2174ad4000]
"XNIO-1 task-3" #24 prio=5 os_prio=0 tid=0x00007f2108005000 nid=0x31cf waiting on condition [0x00007f2174bd5000]
"XNIO-1 task-2" #23 prio=5 os_prio=0 tid=0x00007f2114005000 nid=0x31cc waiting on condition [0x00007f2174cd6000]
"XNIO-1 task-1" #22 prio=5 os_prio=0 tid=0x00007f20f8035000 nid=0x31c2 waiting on condition [0x00007f2174dd7000]
"XNIO-1 Accept" #20 prio=5 os_prio=0 tid=0x00007f219056e800 nid=0x31ba runnable [0x00007f21750d8000]
"XNIO-1 I/O-8" #19 prio=5 os_prio=0 tid=0x00007f219056c800 nid=0x31b9 runnable [0x00007f21751d9000]
"XNIO-1 I/O-7" #18 prio=5 os_prio=0 tid=0x00007f219056a800 nid=0x31b8 runnable [0x00007f21752da000]
"XNIO-1 I/O-6" #17 prio=5 os_prio=0 tid=0x00007f2190568800 nid=0x31b7 runnable [0x00007f21753db000]
"XNIO-1 I/O-5" #16 prio=5 os_prio=0 tid=0x00007f2190566800 nid=0x31b6 runnable [0x00007f21754dc000]
"XNIO-1 I/O-4" #15 prio=5 os_prio=0 tid=0x00007f2190564800 nid=0x31b5 runnable [0x00007f21755dd000]
"XNIO-1 I/O-3" #14 prio=5 os_prio=0 tid=0x00007f2190562800 nid=0x31b4 runnable [0x00007f21756de000]
"XNIO-1 I/O-2" #13 prio=5 os_prio=0 tid=0x00007f2190561000 nid=0x31b3 runnable [0x00007f21757df000]
"XNIO-1 I/O-1" #12 prio=5 os_prio=0 tid=0x00007f219055f800 nid=0x31b2 runnable [0x00007f21758e0000]

Worker Thread ¤ zu »È ¤ ï ¤ ì ¤ ë ¤ è ¤ ¦ ¤ Ë ¤ Ê ¤ à ¤ und ¤ è ¤ ¦ ¤ Ç ¤ ¹ ¡£

Ʊ ¤ ¸ ¥ ¹ ¥ ì ¥ à ¥ É ¤ Ëdispatch ¤ ¹ ¤ ë

HttpServerExchange#dispatch ¤ Ë ¤ Ï¡ ¢ ¤ ¤ ¤ ¯ ¤ Ä ¤ «¥ ª¡¼ ¥ С¼ ¥ í¡¼ ¥ É ¤ µ ¤ ì ¤ und ¥ С¼ ¥ ¸ ¥ ç ¥ ó ¤ zu ¤ ¢ ¤ ê ¤ Þ ¤ ¹ ¡£
http://undertow .io/javadoc/1.4.x/io/undertow/server/HttpServerExchange.html

java.util.concurrent. Executor ¤ òÅÏ ¤ »¤ ëdispatch ¥ á ¥ der l ¥ à ¥ É ¤ â ¤ ¢ ¤ ê¡ ¢ Undertow ¤ ÎÄó¶¡ ¤ ¹ ¤ ëSameThreadExecutor ¤ ò» ÈÍÑ ¤ ¹ ¤ ë ¤ È¡ ¢ Ʊ ¤ ¸ ¥ ¹ ¥ ì ¥ à ¥ É ¤ ǽèÍý ¤ ò³ ¤ ± ¤ ë ¤ è ¤ ¦ ¤ Ë
dispatch ¤ ¹ ¤ ë ¤ ³ ¤ È ¤ zu ¤ Ç ¤ ¤ Þ ¤ ¹ ¡£
src/main/java/org/littlewings/undertow/SameThreadHttpHandler.java

package org.littlewings.undertow;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.SameThreadExecutor;
import org.jboss.logging.Logger;

public class SameThreadHttpHandler implements HttpHandler {
    Logger logger = Logger.getLogger(getClass());

    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {
        logger.infof(
                "%s [%s/%s] access, is io-thread? %b, is blocking? %b",
                LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE),
                Thread.currentThread().getName(),
                Thread.currentThread().getClass().getName(),
                exchange.isInIoThread(),
                exchange.isBlocking());

        exchange.dispatch(SameThreadExecutor.INSTANCE, () ->
                exchange
                        .getResponseSender()
                        .send(
                                String.format(
                                        "Response from: %s/%s, is io-thread? %b, is blocking? %b%n",
                                        Thread.currentThread().getName(),
                                        Thread.currentThread().getClass().getName(),
                                        exchange.isInIoThread(),
                                        exchange.isBlocking()
                                ))
        );
    }
}

SameThreadExecutor ¤ ÎÃæ¿È ¤ Ï¡ ¢ ñ½ã ¤ Ç ¤ ¹ ¤ ± ¤ ì ¤ É¡£

IO Thread ¤ ËÀÚ ¤ êÂØ ¤ ¨ ¤ ë

¤ µ ¤ é ¤ Ë¡ ¢ IO Thread ¤ ËÀÚ ¤ êÂØ ¤ ¨ ¤ ë ¤ ³ ¤ È ¤ â ¤ Ç ¤ ¤ Þ ¤ ¹ ¡£
src/main/java/org/littlewings/undertow/ToIoThreadHttpHandler.java

package org.littlewings.undertow;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.SameThreadExecutor;
import org.jboss.logging.Logger;

public class ToIoThreadHttpHandler implements HttpHandler {
    Logger logger = Logger.getLogger(getClass());

    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {
        logger.infof(
                "%s [%s/%s] access, is io-thread? %b, is blocking? %b",
                LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE),
                Thread.currentThread().getName(),
                Thread.currentThread().getClass().getName(),
                exchange.isInIoThread(),
                exchange.isBlocking());

        if (!exchange.isInIoThread()) {
            exchange.dispatch(exchange.getIoThread());
            logger.infof("return, dispatch to io");
            return;
        }

        exchange.dispatch(SameThreadExecutor.INSTANCE, () ->
                exchange
                        .getResponseSender()
                        .send(
                                String.format(
                                        "Response from: %s/%s, is io-thread? %b, is blocking? %b%n",
                                        Thread.currentThread().getName(),
                                        Thread.currentThread().getClass().getName(),
                                        exchange.isInIoThread(),
                                        exchange.isBlocking()
                                )
                        ));
    }
}

¤ ³ ¤ ³ ¤ Ç ¤ Ï¡ ¢ IO Thread ¤ Ç ¤ Ê ¤ ± ¤ ì ¤ ÐIO Thread ¤ Ëdispatch ¤ ¹ ¤ ë ¤ È ¤ ¤ ¤ ¦ ÆâÍÆ ¤ Ë ¤ Ê ¤ à ¤ Æ ¤ ¤ ¤ Þ ¤ ¹ ¡£

        if (!exchange.isInIoThread()) {
            exchange.dispatch(exchange.getIoThread());
            logger.infof("return, dispatch to io");
            return;
        }

¤ ³ ¤ Î¾ì ¹ ç¡ ¢ dispatch ¤ ΰú¿ô ¤ ÏRunnable ¤ È ¤ · ¤ Æ °· ¤ ï ¤ ì ¤ Æ ¤ ¤ ¤ Þ ¤ ¹ ¡£

¶Ëü ¤ Ê ¤ ³ ¤ È ¤ ò ¤ ¹ ¤ ë ¤ È¡ ¢ Àè ¤ Û ¤ ɺîÀ® ¤ · ¤ ¿Worker Thread ¤ ËÀÚ ¤ êÂØ ¤ ¨ ¤ ëHttpHandler ¤ «¤ é¡ ¢ ¤ µ ¤ é ¤ ËIO Thread ¤ ËÀÚ ¤ êÂØ ¤ ¨ ¤ ë ¤ ß ¤ und ¤ ¤ ¤ Ê ¤ ³ ¤ È ¤ zu ¤ Ç ¤ ¤ Þ ¤ ¹ ¡£
src/main/java/org/littlewings/undertow/DispatchWorkerHttpHandler.java

package org.littlewings.undertow;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import org.jboss.logging.Logger;

public class DispatchWorkerHttpHandler implements HttpHandler {
    Logger logger = Logger.getLogger(getClass());

    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {
        logger.infof(
                "%s [%s/%s] access, is io-thread? %b, is blocking? %b",
                LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE),
                Thread.currentThread().getName(),
                Thread.currentThread().getClass().getName(),
                exchange.isInIoThread(),
                exchange.isBlocking());

        if (exchange.isInIoThread()) {
            exchange.dispatch(this);
            logger.infof("return, dispatch to worker");
            return;
        }

        exchange.dispatch(exchange.getIoThread(), new ToIoThreadHttpHandler());
    }
}

¤ ³ ¤ Î¾ì ¹ ç¡ ¢ HttpServerExchange#getIoThread ¤ ò »È ¤ à ¤ Ædispatch ¤ ¹ ¤ ë ¤ È ¤ ³ ¤ í ¤ zu ¥ Ý ¥ ¤ ¥ ó ¥ È ¤ Ç ¤ ¹ ¡£

        exchange.dispatch(exchange.getIoThread(), new ToIoThreadHttpHandler());

Blocking¡ ©

¤ È ¤ ³ ¤ í ¤ Ç¡ ¢ ¤ ³ ¤ ³ ¤ Þ ¤ Ç ¤ º ¤ Ã ¤ È

exchange.isBlocking()

¤ È ¤ «¤ Ç ¥ Ö ¥ í ¥ à ¥ ¥ ó ¥ ° ¤« ¤ É ¤ ¦ ¤ «¤ ò ¸« ¤ Æ ¤ ¤ ¤ und ¤ Î ¤ Ç ¤ ¹ ¤ ¬¡ ¢ ¼Â ¤ Ï ¤ ³ ¤ ì¡ ¢ ¤ ¤ ¤ Ä ¤ âfalse ¤ Ç ¤ ¹ ¡£

¤ ³ ¤ ì ¤ ¬true ¤ òÊÖ ¤ ¹ ¤ è ¤ ¦ ¤ Ë ¤ Ê ¤ ë ¤ Ë ¤ Ï¡ ¢ HttpServerExchange#startBlocking ¤ ¹ ¤ ëɬÍ× ¤ zu ¤ ¢ ¤ ê ¤ Þ ¤ ¹ ¡£

Non-blocking IO

Blocking IO

HttpServerExchange#startBlocking ¤ ò »È ¤ ¦ ¤ ³ ¤ È ¤ Ç¡ ¢ ¥ Ö ¥ í ¥ à ¥ ¥ ó ¥ °IO ¤ ÎAPI ¤ ò» È ¤ ¦ ¤ ³ ¤ È ¤ zu ¤ Ç ¤ ¤ ë ¤ è ¤ ¦ ¤ Ë ¤ Ê ¤ ê ¤ Þ ¤ ¹ ¡£

Undertow ¤ ÎServlet¼ÂÁõ ¤ ¬¡ ¢ ¤ ³ ¤ ì ¤ ò »È ¤ à ¤ Æ ¤ ¤ ¤ Þ ¤ ¹ ¡£
https://a#L185

¤ Ç¡ ¢ Worker Thread ¤ ËÀÚ ¤ êÂØ ¤ ¨ ¤ Þ ¤ ¹ ¡ ¢ ¤ È¡£
https://a#L193-L196

Ãí°ÕÅÀ ¤ È ¤ · ¤ Æ ¤ Ï¡ ¢ HttpServerExchange#startBlocking ¤ · ¤ ¿¸å ¤ Ï¡ ¢ Blocking IO ¤ ò »È ¤ ¦ ¤ ³ ¤ È ¤ Ë ¤ Ê ¤ ë ¤ Î ¤ Ç¡ ¢ IO Thread ¤« ¤ éRead¡¿Write ¤ Ï
¶Ø »ß ¤ µ ¤ ì ¤ Þ ¤ ¹ ¡£
https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/UndertowInputStream.java#L83-L85
https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/UndertowOutputStream.java#L112-L114

¤ ³ ¤ ÎstartBlocking ¤ ò »È ¤ ¦ Á° ¤ Ï¡ ¢ ¥ ê ¥ ¯ ¥ ¨ ¥ ¹ ¥ È¡¿ ¥ ì ¥ ¹ ¥ Ý ¥ ó ¥ ¹ ¤ Ø ¤ ÎÆþ½ÐÎÏ ¤ ÏAsync ¤ ÊSender¡¿Receiver ¤ ¬ÍøÍÑ ¤ µ ¤ ì ¤ Æ ¤ ¤ ¤ Þ ¤ ¹ ¡£
https://32
https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/AsyncSenderImpl.java
https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/AsyncReceiverImpl.java

startBlocking ¤ ¹ ¤ ë ¤ ³ ¤ È ¤ Ç¡ ¢ Blocking ¤ ÊSender¡¿Receiver ¤ zu »È ¤ ï ¤ ì ¤ ë ¤ è ¤ ¦ ¤ Ë ¤ Ê ¤ ê ¤ Þ ¤ ¹ ¡£
https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/BlockingSenderImpl.java
https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/io/BlockingReceiverImpl.java

startBlocking ¤ Ç¡ ¢ HttpServerExchangeÃæ ¤ ËBlockingHttpExchange ¤ Ø ¤ Î »² ¾È ¤ ¬ºî ¤ é ¤ ì ¤ ë ¤ è ¤ ¦ ¤ Ë ¤ Ê ¤ ê ¤ Þ ¤ ¹ ¤ è¡ ¢ ¤ È¡£
https://92

¤ â ¤ ¦ ¤ Á ¤ ç ¤ à ¤ È ¥ ¹ ¥ ì ¥ à ¥ É ¤ δÉÍý ¤ ò ¸«¤ Æ ¤ ß ¤ è ¤ ¦

¥ ¹ ¥ ì ¥ à ¥ É ¥ À ¥ ó ¥ × ¤ ò¼è ¤ à ¤ und »þ ¤ Ë¡ ¢ ¤ ³ ¤ ó ¤ Ê ´ ¶ ¤ ¸ ¤ Î ¥ ¹ ¥ ì ¥ à ¥ É ¤ zu ¤ ï ¤ é ¤ ï ¤ é ¤ ȸ½ ¤ ì ¤ Þ ¤ · ¤ ¿¡£

"XNIO-1 task-4" #25 prio=5 os_prio=0 tid=0x00007f210c005000 nid=0x31d2 waiting on condition [0x00007f2174ad4000]
"XNIO-1 task-3" #24 prio=5 os_prio=0 tid=0x00007f2108005000 nid=0x31cf waiting on condition [0x00007f2174bd5000]
"XNIO-1 task-2" #23 prio=5 os_prio=0 tid=0x00007f2114005000 nid=0x31cc waiting on condition [0x00007f2174cd6000]
"XNIO-1 task-1" #22 prio=5 os_prio=0 tid=0x00007f20f8035000 nid=0x31c2 waiting on condition [0x00007f2174dd7000]
"XNIO-1 Accept" #20 prio=5 os_prio=0 tid=0x00007f219056e800 nid=0x31ba runnable [0x00007f21750d8000]
"XNIO-1 I/O-8" #19 prio=5 os_prio=0 tid=0x00007f219056c800 nid=0x31b9 runnable [0x00007f21751d9000]
"XNIO-1 I/O-7" #18 prio=5 os_prio=0 tid=0x00007f219056a800 nid=0x31b8 runnable [0x00007f21752da000]
"XNIO-1 I/O-6" #17 prio=5 os_prio=0 tid=0x00007f2190568800 nid=0x31b7 runnable [0x00007f21753db000]

¤ ³ ¤ ì ¤ é ¤ ò¡ ¢ ¤ â ¤ ¦ ¾¯ ¤ · ¸ «¤ Æ ¤ ß ¤ und ¤ ¤ ¤ È» × ¤ ¤ ¤ Þ ¤ ¹ ¡£

IO Thread ¤ â´Þ ¤ á ¤ Æ¡ ¢ Worker ¤ È ¤ ¤ ¤ ¦ ° · ¤ ¤ ¤ Ë ¤ Ê ¤ Ã ¤ Æ ¤ ¤ ¤ ë ¤ Ã ¤ Ý ¤ ¤ ¡Ä¡ ©
https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/Undertow.java#L119

¥ ¹ ¥ ì ¥ à ¥ É ¤ κîÀ® ¤ Ï¡ ¢ XNIO ¦ ¤ Ë ¤ Ê ¤ ê ¤ Þ ¤ ¹ ¡£
https://github.com/xnio/xnio/blob/3.3.8.Final/api/src/main/java/org/xnio/Xnio.java#L476-L511
https://github.com/xnio/xnio/blob/3.3.8.Final/nio-impl/src/main/java/org/xnio/nio/NioXnio.java#L202

IO Thread ¤ È¡ ¢ Accept ¤ ò´ÉÍý ¤ ¹ ¤ ë ¥ ¹ ¥ ì ¥ à ¥ É ¤ ¬ºî ¤ é ¤ ì ¤ ë ¤ Î ¤ ÏNioXnioWorker ¤ Î ¤ è ¤ ¦ ¤ Ç ¤ ¹ ¤ Í¡£
https://github.com/xnio/xnio/blob/3.3.8.Final/nio-impl/src/main/java/org/xnio/nio/NioXnioWorker.java#L96-L107

¤ der l ¤ ÎNioXnioWorker ¤ Î¿Æ ¥ ¯ ¥ é ¥ ¹ ¤ Ç ¤ ¢ ¤ ëXniWorker ¤ ¬¡ ¢ Worker Thread ¤ δÉÍý ¤ ò ¤ · ¤ Æ ¤ ¤ ¤ Þ ¤ ¹ ¡£
https://github.com/xnio/xnio/blob/3.3.8.Final/api/src/main/java/org/xnio/XnioWorker.java#L117-L124
https://github.com/xnio/xnio/blob/3.3.8.Final/api/src/main/java/org/xnio/XnioWorker.java#L954

HttpServerExchange#dispatch ¤ ÇWorker Thread ¤ ˰Ѿù ¤ µ ¤ ì ¤ ë ¤ Î ¤ Ï¡ ¢ ¸½ºß ¤ ÎÀܳ ¤ «¤ éXniWorker ¤ ¬¼èÆÀ ¤ Ç ¤ ¡ ¢ ¤ der l ¤ ³ ¤« ¤ éexecute ¤ ¹ ¤ ë ¤ È
https://github.com/undertow-io/undertow/blob/1.4.20.Final/core/src/main/java/io/undertow/server/HttpServerExchange.java#L795

XniWorker ¤ ¬´ÉÍý ¤ · ¤ Æ ¤ ¤ ¤ ëTaskPool ¤ ËÆÍ ¤ à ¹ þ ¤ Þ ¤ ì ¤ ë ¤ «¤ é ¤ Ç ¤ ¹ ¤ Í¡£
https://github.com/xnio/xnio/blob/3.3.8.Final/api/src/main/java/org/xnio/XnioWorker.java#L748-L750

¤ Ê ¤ ª¡ ¢ HttpServerExchange#getIoThread ¤ ò ¹ Ô ¤ ¦ ¤ È¡ ¢ ¸½ºß ¤ ÎÀܳ ¤ Ëɳ ¤ Å ¤ ¤ ¤ Æ ¤ ¤ ¤ ëIO Thread ¤ òľÀܼèÆÀ ¤ Ç ¤ ¤ Þ ¤ ¹ ¡£
https://69

Ìá ¤ êÃÍ ¤ η¿ ¤ ÏXnioIoThread ¤ Ç ¤ ¹ ¤ ¬¡ ¢ Àè ¤ Û ¤ ÉNioXnioWorker ¤ ǺîÀ® ¤ · ¤ Æ ¤ ¤ ¤ ¿IO Thread ¤ Ï¡ ¢ WorkerThread ¤ È ¤ ¤ ¤ ¦ ¥ ¯ ¥ é ¥ ¹ ¤ Ç ¤ · ¤ ¿¡£
https://github.com/xnio/xnio/blob/3.3.8.Final/nio-impl/src/main/java/org/xnio/nio/WorkerThread.java#L79

¤ ³ ¤ ì ¤ Ï¡ ¢ XnioIoThread ¤ Î ¥ µ ¥ Ö ¥ ¯ ¥ é ¥ ¹ ¤ Ç ¤ ¹ ¡£

Worker Thread ¤ Ï ¤ É ¤ ¦ ¤ Ê ¤ Î ¤ «¡ © ¤ Õ ¤ Ä ¤ ¦ ¤ ÎThread ¤ Ç ¤ ¹ ¤ Í¡£
https://github.com/xnio/xnio/blob/3.3.8.Final/api/src/main/java/org/xnio/XnioWorker.java#L954

¤ der l ¤ ¦ ¤ ¤ ¤ ¨ ¤ С ¢ curl ¤ ηë²Ì ¤ ÇÌá ¤ à ¤ Æ ¤ ¤ und ¥ ¹ ¥ ì ¥ à ¥ É ¤ Î ¥ ¯ ¥ é ¥ ¹ ̾ ¤ â¡ ¢ IO Thread ¤ ¬WorkerThread ¤ Ç

$ curl http://localhost:8080
Response from: XNIO-1 I/O-1/org.xnio.nio.WorkerThread, is io-thread? true, is blocking? false

Worker Thread ¤ ¬Thread ¤ Ç ¤ · ¤ und ¤ Í¡£

$ curl http://localhost:8080
Response from: XNIO-1 task-5/java.lang.Thread, is io-thread? false, is blocking? false

¤ Þ ¤ È ¤ á

¤ Á ¤ ç ¤ à ¤ È ¤ · ¤ ¿Íýͳ ¤ «¤ é ¤ Ê ¤ Î ¤ Ç ¤ ¹ ¤ ¬¡ ¢ Undertow ¤ Ç ¤ ÎIO Thread¡ ¢ Worker Thread ¤ ÎÀÚ ¤ êÂØ ¤ ¨ ¤ ä¡ ¢ ¥ ¹ ¥ ì ¥ à ¥ É ¤ Þ ¤ ï ¤ ê ¤ ò ¤ Á ¤ ç ¤ à ¤ ÈÄÉ ¤ à ¤ Æ ¤ ß ¤ Þ ¤ · ¤ ¿¡£

Á°¡ ¹ ¤ «¤ 龯 ¤ · ¤ ϵ ¤ ¤ Ë ¤ Ê ¤ à ¤ Æ ¤ ¤ ¤ ¿²Õ½ê ¤ Ê ¤ Î ¤ Ç ¤ ¹ ¤ ¬¡ ¢ °Õ ³° ¤ ÈÌÌÇò ¤« ¤ à ¤ und ¤ Ç ¤ ¹ ¡£

¥ ¹ ¥ Ñ ¥ àÂкö ¤ Î ¤ und ¤ á ¤ Î ¥ À ¥ ß¡¼ ¤ Ç ¤ ¹ ¡£ ¤ â ¤ · ¸ «¤ ¨ ¤ Æ ¤ ⲿ ¤ âÆþÎÏ ¤ · ¤ Ê ¤ ¤ ¤ Ç ¤ ¯ ¤ À ¤ µ ¤ ¤
¥²¥¹¥È


²èÁüÇ § ¾ Ú

¥ È ¥ é ¥ Ã ¥ ¯ ¥ Ð ¥ Ã ¥ ¯ - http://d.hatena.ne.jp/Kazuhira/20170930/1506743975