深入理解Java三种IO模式和Epoll模型

本文深入探讨了Java中的三种IO模型:BIO、NIO和AIO。BIO是同步阻塞模型,适合连接数目固定且较少的情况;NIO是同步非阻塞,通过多路复用器(如Selector)提高效率,但存在大量无效遍历的问题;AIO是异步非阻塞,适用于连接多且连接时间长的场景。文章还详细解释了Epoll在NIO中的作用和优势,以及Netty选择使用NIO而非AIO的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IO模型

IO模型就是说用什么样的通道进行数据的发送和接收,Java共支持3种网络编程IO模式:BIO,NIO,AIO

BIO(Blocking IO )

同步阻塞模型,一个客户端连接对应一个处理线程

BIO代码示例:



import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Handler;

public class SocketServer {

    public static void main(String[] args) throws  Exception {

        ServerSocket serverSocket = new ServerSocket(9000);
        while (true){
            System.out.println("等待连接");
            //阻塞连接
            Socket clientSocket = serverSocket.accept();
            System.out.println("有客户端连接。。。");
//            handle(clientSocket);

            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        handle(clientSocket);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }

    public  static void handle(Socket clientSocket) throws  Exception{
        byte[] bytes = new byte[1024];
        System.out.println("准备read。。");
        //接收客户端的数据,阻塞方法,没有数据可读时就阻塞
        int read = clientSocket.getInputStream().read(bytes);
        System.out.println("read 完毕。");
        if (read !=-1){
            System.out.println("接收到客户端数据:" + new String(bytes,0,read));
        }
        clientSocket.getOutputStream().write("helloClient".getBytes());
        clientSocket.getOutputStream().flush();
    }
}
//客户端代码


import java.io.IOException;
import java.net.Socket;

public class SocketClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 9000);
        //向服务端发送数据
        socket.getOutputStream().write("HelloServer".getBytes());
        socket.getOutputStream().flush();
        System.out.println("向服务端发送数据结束");
        byte[] bytes = new byte[1024];
        //接收服务端回传的数据
        socket.getInputStream().read(bytes);
        System.out.println("接收到服务端的数据:" + new String(bytes));
        socket.close();
    }
}

缺点:

从上面的代码我们可以看出来,BIO代码中连接事件和读写数据事件都是阻塞的,所以这种模式的缺点非常的明显

1、如果我们连接完成以后,不做读写数据操作会导致线程阻塞,浪费资源

2、如果没来一个连接我们都需要启动一个线程处理,那么会导致服务器线程太多,压力太大,比如C10K;

应用场景:

BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,但是程序比较简单。

NIO(Non Blocking IO)

同步非阻塞模型,服务器实现模式为一个线程可以处理多个请求连接,客户端发送的连接请求都会注册到多路复用器(selector)上,多路复用器轮询到连接有IO请求就进行处理,JDK1.4开始引入。

//没有引入多路复用器的代码

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.chan
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

g-Jack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值