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课程的理解

相关推荐
tg-zm8899963 小时前
2025返利商城源码/挂机自动收益可二开多语言/自定义返利比例/三级分销理财商城
java·mysql·php·laravel·1024程序员节
X***C8623 小时前
SpringBoot:几种常用的接口日期格式化方法
java·spring boot·后端
前端达人3 小时前
你的App消息推送为什么石沉大海?看Service Worker源码我终于懂了
java·开发语言
小光学长3 小时前
基于ssm的宠物交易系统的设计与实现850mb48h(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·前端·数据库
编程大师哥3 小时前
vxe-table 透视表分组汇总及排序基础配置
java
8***84823 小时前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
9***J6283 小时前
Spring Boot项目集成Redisson 原始依赖与 Spring Boot Starter 的流程
java·spring boot·后端
M***Z2104 小时前
SQL 建表语句详解
java·数据库·sql
v***7944 小时前
Spring Boot 热部署
java·spring boot·后端
执笔论英雄4 小时前
【RL】python协程
java·网络·人工智能·python·设计模式