【从BIO到Netty】2.NIO线程模型

2021-05-08 01:30

阅读:703

标签:客户端连接   print   计算   string   lazy   min   import   了解   load   

要解决BIO存在的性能问题,本质上是要做到:
1. 让线程不再阻塞
2. 让一个线程能处理多个客户端连接

NIO线程模型,如下图所示

技术图片

 

 

"计算机科学中的一切问题,都可以通过增加中间层来解决",在NIO的设计中被体现了出来。
所以实际上selector, channel, 以及buffer,本质上都是为了解耦

下面以NIO的方式,重写一下EchoServer,直观体验一下JDK的NIO

 

package org.scaventz.nio.mine;


import io.netty.util.CharsetUtil;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NioEchoServer {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(8080));
        // 设置为非阻塞
        serverSocketChannel.configureBlocking(false);

        // 获得一个 Selector 对象
        Selector selector = Selector.open();
        // 将我们的 serverSocketChannel 注册到 selector上,注册的事件为 ACCEPT事件
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            // 阻塞等待,也可以选择不阻塞 比如select(1000),等待1ms
            selector.select();
            Set keys = selector.selectedKeys();
            Iterator keysIterator = keys.iterator();
            while (keysIterator.hasNext()) {
                SelectionKey key = keysIterator.next();
                if (key.isAcceptable()) {
                    System.out.println("连接事件到来");
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(4096));
                    keysIterator.remove();
                    continue;
                }
                if (key.isReadable()) {
                    SocketChannel channel = (SocketChannel) key.channel();
                    ByteBuffer buffer = (ByteBuffer) key.attachment();
                    channel.read(buffer);
                    System.out.print("收到客户端信息: " + new String(buffer.array(), CharsetUtil.UTF_8));
                    // 回复客户端
                    channel.write(buffer);
                    keysIterator.remove();
                }
            }
        }
    }
}

 

【从BIO到Netty】2.NIO线程模型

标签:客户端连接   print   计算   string   lazy   min   import   了解   load   

原文地址:https://www.cnblogs.com/heben/p/13179467.html


评论


亲,登录后才可以留言!