netty(三):NIO——多线程优化

NIO多线程优化

  • 使用Boss线程来处理accepct事件
  • 使用Worker线程来处理读写事件,可以创建多个worker线程
java 复制代码
package com.review;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;

@Slf4j
public class MultiServer {
    public static void main(String[] args) throws IOException {
        Thread.currentThread().setName("BOSS");
        Selector selector = Selector.open();
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);
        ssc.bind(new InetSocketAddress(11027));
        SelectionKey sscKey = ssc.register(selector, 0, null);
        sscKey.interestOps(SelectionKey.OP_ACCEPT);
        Worker worker = new Worker("worker-0");
        while (true){
            selector.select();

            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                iterator.remove();

                if (key.isAcceptable()){
                    ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
                    SocketChannel sc = serverSocketChannel.accept();
                    sc.configureBlocking(false);
                    worker.register(sc);
                    worker.selector.wakeup();
                }
            }
        }

    }

    static class Worker implements Runnable{
        private String name;

        private Selector selector;

        private Thread thread;

        private volatile boolean start;

        ConcurrentLinkedQueue<Runnable> queue = new ConcurrentLinkedQueue<>();

        public Worker(String name){
            this.name = name;
        }

        public void register(SocketChannel sc) throws IOException {
            if (!start){
                selector = Selector.open();
                thread = new Thread(this,this.name);
                thread.start();
                start = true;
            }
            queue.add(()->{
                try {
                    SelectionKey scKey = sc.register(selector, 0, null);
                    scKey.interestOps(SelectionKey.OP_READ);
                } catch (ClosedChannelException e) {
                    log.error(e.getMessage(),e);
                }
            });
        }

        @Override
        public void run() {
            while (true){
                try {
                    selector.select();
                } catch (IOException e) {
                    log.error(e.getMessage(),e);
                }
                if (queue.size() > 0){
                    queue.poll().run();
                }
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()){
                    SelectionKey selectionKey = iterator.next();
                    iterator.remove();

                    if (selectionKey.isReadable()){
                        SocketChannel channel = (SocketChannel) selectionKey.channel();
                    }

                }
            }
        }
    }
}

------------本专栏来自于对满叔在b站所讲的netty课程的理解

相关推荐
界面开发小八哥14 分钟前
Java开发工具IntelliJ IDEA v2025.1——全面支持Java 24、整合AI
java·ide·人工智能·intellij-idea·idea
普兰店拉马努金1 小时前
【高中数学/古典概率】4红2黑六选二,求取出两次都是红球的概率
java·概率
智商低情商凑1 小时前
CAS(Compare And Swap)
java·jvm·面试
yangmf20401 小时前
使用 Logstash 迁移 MongoDB 数据到 Easysearch
java·elasticsearch·搜索引擎
Tiger_shl1 小时前
【Python语言基础】24、并发编程
java·数据库·python
FAQEW1 小时前
Spring boot 中的IOC容器对Bean的管理
java·spring boot·后端·bean·ioc容器
0509151 小时前
测试基础笔记第十一天
java·数据库·笔记
IDRSolutions_CN1 小时前
如何将 PDF 中的文本提取为 JSON 格式
java·经验分享·pdf·软件工程·团队开发
摘星编程2 小时前
并发设计模式实战系列(6):读写锁
java·设计模式·并发编程
Java中文社群2 小时前
最火向量数据库Milvus安装使用一条龙!
java·人工智能·后端