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

相关推荐
现在,此刻6 分钟前
java面试题储备4: 谈谈对es的理解
java·开发语言·elasticsearch
骇客野人8 分钟前
java实用工具类
java·开发语言·python
油丶酸萝卜别吃8 分钟前
java中在多线程的情况下安全的修改list
java·安全·list
HuiSoul2005 小时前
Spring MVC
java·后端·spring mvc
摇滚侠7 小时前
面试实战 问题二十四 Spring 框架中循环依赖问题的解决方法
java·后端·spring
三木水9 小时前
Spring-rabbit使用实战七
java·分布式·后端·spring·消息队列·java-rabbitmq·java-activemq
别来无恙1499 小时前
Spring Boot文件下载功能实现详解
java·spring boot·后端·数据导出
optimistic_chen9 小时前
【Java EE初阶 --- 网络原理】JVM
java·jvm·笔记·网络协议·java-ee
weixin_4569042710 小时前
Java泛型与委托
java·spring boot·spring
悟能不能悟10 小时前
能刷java题的网站
java·开发语言