NIO入门

IO和NIO的区别:

  1. IO:通过流处理数据,仅支持阻塞IO。
    核心组件:**InputStream /OutputStream用于字节的读写,Reader / Writer:用于字符流的读写。**读取过程中无法被中断,是阻塞式IO。

  2. NIO:通过管道处理数据,支持阻塞IO和非阻塞IO。

    核心组件:**Channel通道、Buffer缓冲区、Selector选择器。**Channel与Buffer做直接交互,用于数据的传输,支持非阻塞IO,Buffer用于存放数据,Selector用于管理多个管道,允许单个线程处理多个IO。


Channel与Buffer联调

阻塞IO案例

ServerSocketChannel.accept():该方法用于等待客户端连接,直到有客户端连接才会返回,如果没有客户端连接则会一直阻塞。

SocketChannel.read(ByteBuffer):改方法用于接收客户端的数据,直到有数据才会返回,否则将一直阻塞线程。

java 复制代码
    package com.jiawa.netty.server;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.List;
    
    import static com.jiawa.netty.utils.ByteBufferUtil.debugAll;
    
    public class Server {
        private static final Logger logger = LoggerFactory.getLogger(Server.class);
    
        public static void main(String[] args) throws IOException {
            //创建缓存、缓存客户端信息
            ByteBuffer buffer = ByteBuffer.allocate(16);
    
            //创建服务器
            ServerSocketChannel server = ServerSocketChannel.open();
    
    
            //绑定端口
            server.bind(new InetSocketAddress(8080));
    
            //创建客户端存储集合
            List<SocketChannel> clients = new java.util.ArrayList<>();
    
            //接收客户端
            while (true) {
                //阻塞线程,直到有客户端请求连接后释放
                SocketChannel client = server.accept();
    
                //如果有客户端请求,则返回客户端信息
                logger.info("收到客户端请求:{}", client);
                clients.add(client);
    
                for (SocketChannel c : clients) {
                    //读取客户端数据
                    int read = c.read(buffer);
                    if (read > 0) {
                        logger.info("读取客户端数据:{}", read);
                        //打开读
                        buffer.flip();
                        //打印数据
                        debugAll(buffer);
                        //清空
                        buffer.clear();
                    }
    
                }
            }
        }
    }

非阻塞IO案例

server.configureBlocking(false):将 ServerSocketChannel 设置为非阻塞模式。

client.configureBlocking(false):将每个 SocketChannel 设置为非阻塞模式。

设置为非阻塞之后,则不会阻塞线程,不管是否有客户端连接或者接收客户端数据,都会直接返回,不会阻塞线程。

java 复制代码
package com.jiawa.netty.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.List;

import static com.jiawa.netty.utils.ByteBufferUtil.debugAll;

public class Server {
    private static final Logger logger = LoggerFactory.getLogger(Server.class);

    public static void main(String[] args) throws IOException {
        //创建缓存、缓存客户端信息
        ByteBuffer buffer = ByteBuffer.allocate(16);

        //创建服务器
        ServerSocketChannel server = ServerSocketChannel.open();

        //非阻塞
        if (server!= null){
            server.configureBlocking(false);
        }

        //绑定端口
        server.bind(new InetSocketAddress(8080));

        //创建客户端存储集合
        List<SocketChannel> clients = new java.util.ArrayList<>();

        //接收客户端
        while (true) {
            //阻塞线程,直到有客户端请求连接后释放
            SocketChannel client = server.accept();

            //将客户端设置为非阻塞
            if (client != null) {
                client.configureBlocking(false);
            }

            //如果有客户端请求,则返回客户端信息
            if (client != null) {
                logger.info("收到客户端请求:{}", client);
                clients.add(client);
            }


            for (SocketChannel c : clients) {
                //读取客户端数据
                int read = c.read(buffer);
                if (read > 0){
                    logger.info("读取客户端数据:{}", read);
                    //打开读
                    buffer.flip();
                    //打印数据
                    debugAll(buffer);
                    //清空
                    buffer.clear();
                }

            }
        }
    }
}
相关推荐
眼镜哥(with glasses)42 分钟前
Java程序题案例分析
java·开发语言
全栈凯哥2 小时前
备忘录模式(Memento Pattern)详解
java·设计模式·备忘录模式
纪元A梦4 小时前
华为OD机试真题——荒岛求生(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
java·c语言·javascript·c++·python·华为od·go
苹果酱05674 小时前
iview 表单验证问题 Select 已经选择 还是弹验证提示
java·vue.js·spring boot·mysql·课程设计
夏子曦5 小时前
C#——NET Core 中实现汉字转拼音
开发语言·c#
꧁坚持很酷꧂6 小时前
Qt天气预报系统绘制温度曲线
开发语言·qt
电商数据girl6 小时前
【Python爬虫电商数据采集+数据分析】采集电商平台数据信息,并做可视化演示
java·开发语言·数据库·爬虫·python·数据分析
海尔辛6 小时前
学习黑客Bash 脚本
开发语言·学习·bash
夏季疯6 小时前
学习笔记:黑马程序员JavaWeb开发教程(2025.3.30)
java·笔记·学习