Почему цикл обработки событий использует более одного потока? - PullRequest
0 голосов
/ 10 января 2019

Я всегда думал, что асинхронность - это эффективное использование ресурсов и безопасность потоков, но сегодня я столкнулся со странным поведением Нетти.

public class Example {
    public static void main(String[] args) throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        ServerBootstrap bootstrap = new ServerBootstrap();
        try {
            bootstrap.group(group)
                     .channel(NioServerSocketChannel.class)
                     .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel channel) {
                            channel.pipeline()
                                   .addLast(new ChannelOutboundHandlerAdapter() {
                                        @Override
                                        public void read(ChannelHandlerContext ctx) {
                                            String id = String.valueOf(Thread.currentThread().getId());
                                            ctx.writeAndFlush(Unpooled.wrappedBuffer(id.getBytes(StandardCharsets.UTF_8)))
                                               .addListener(ChannelFutureListener.CLOSE);
                                            }
                                        });
                        }
                    })
                    .bind("localhost", 1234)
                    .sync()
                    .channel()
                    .closeFuture()
                    .syncUninterruptibly();
        } finally {
            group.shutdownGracefully()
                 .syncUninterruptibly();
        }
    }
}

Когда я подключился в первый раз, я получил 16. Затем 17, 18, 19 и т. Д. Каждое соединение выполняется в новом потоке! Зачем? Какой смысл в Netty, если он многопоточный?

1 Ответ

0 голосов
/ 10 января 2019

NioEventLoopGroup использует рабочие потоки для использования нескольких ядер ЦП. Согласно конструктор без аргументов javadoc :

NioEventLoopGroup ()

Создайте новый экземпляр, используя количество потоков по умолчанию, ThreadFactory по умолчанию и SelectorProvider, который возвращается SelectorProvider.provider ().

Количество потоков по умолчанию согласно MultithreadEventLoopGroup будет вдвое больше числа доступных процессоров:

DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
            "io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));

Как правило, этого должно быть достаточно для насыщения процессора без создания огромного количества потоков. Создайте слишком мало потоков, и вы не получите полную загрузку процессора. Создайте слишком много, и вы потратите значительное время на переключение контекста между ними.

...