NIO之非阻塞模式

NIO支持非阻塞模式,以网络连接和网络数据传输为例。如果使用阻塞模式,ServerSocketChannel在调用accept等待客户端建立连接是阻塞的,没有连接就一直阻塞。从Channel中读取客户端传送的数据也是阻塞的,没有数据就一直阻塞。当我们开启非阻塞模式,等待连接建立时没有连接就返回null,等到数据时没有数据就返回0。

java 复制代码
// 使用 nio 来理解非阻塞模式, 单线程
// 0. ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(16);
// 1. 创建了服务器
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false); // 非阻塞模式
// 2. 绑定监听端口
ssc.bind(new InetSocketAddress(8080));
// 3. 连接集合
List<SocketChannel> channels = new ArrayList<>();
while (true) {
    // 4. accept 建立与客户端连接, SocketChannel 用来与客户端之间通信
    SocketChannel sc = ssc.accept(); // 非阻塞,线程还会继续运行,如果没有连接建立,但sc是null
    if (sc != null) {
        log.debug("connected... {}", sc);
        sc.configureBlocking(false); // 非阻塞模式
        channels.add(sc);
    }
    for (SocketChannel channel : channels) {
        // 5. 接收客户端发送的数据
        int read = channel.read(buffer);// 非阻塞,线程仍然会继续运行,如果没有读到数据,read 返回 0
        if (read > 0) {
            buffer.flip();
            debugRead(buffer);
            buffer.clear();
            log.debug("after read...{}", channel);
        }
    }
}

以上虽然是非阻塞模式,但是如果一直没有连接或者数据接收,会导致CPU空转,造成资源浪费。为此,最佳方式是使用Selector,其支持单线程绑定多个channel监听对应类型的事件,在防止完全非阻塞模式CPU空转的同时也避免了传统的完全阻塞模式下阻塞等待影响其他需要连接或有数据接收的channel的正常工作,这也就是NIO Selector的作用,后续会详细介绍。

相关推荐
图图图图爱睡觉2 分钟前
主机跟虚拟机ip一直Ping不通,并且虚拟机使用ifconfig命令时,ens33没有ipv4地址,只有ipv6地址
服务器·网络·tcp/ip
deephub15 分钟前
FastMCP 入门:用 Python 快速搭建 MCP 服务器接入 LLM
服务器·人工智能·python·大语言模型·mcp
lhxcc_fly27 分钟前
Linux网络--8、NAT,代理,网络穿透
linux·服务器·网络·nat
chxii32 分钟前
Maven 详解(上)
java·maven
李少兄34 分钟前
IntelliJ IDEA 远程调试(Remote Debugging)教程
java·ide·intellij-idea
Kuo-Teng38 分钟前
Leetcode438. 找到字符串中所有字母异位词
java·算法·leetcode
毕设小屋vx ylw2824261 小时前
Java开发、Java Web应用、前端技术及Vue项目
java·前端·vue.js
wow_DG1 小时前
【运维✨】云服务器公网 IP 迷雾:为什么本机看不到那个地址?
运维·服务器·tcp/ip
TDengine (老段)1 小时前
TDengine 字符串函数 CHAR 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
float_com1 小时前
【java基础语法】------ 数组
java