传统IO和NIO的区别

NIO与传统IO对比
传统IO

看以下代码:

  public class OioServer {
    public static void main(String[] args) {
        // 创建socket服务 监听10101端口
        try {
            ServerSocket serverSocket = new ServerSocket(10101);
            System.out.println("服务器启动了");
            while (true) {
                // 获取一个套接字(阻塞)
                Socket socket = serverSocket.accept();
                System.out.println("来一个新的客户端");
                handler(socket);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void handler(Socket socket) {
        try {
            byte[] bytes = new byte[1024];
            // 获取输入流
            InputStream inputStream = socket.getInputStream();
            while (true) {
                // 读取数据(阻塞)
                int read = inputStream.read(bytes);
                if (read != -1) {
                    System.out.println(new String(bytes, 0, read));

                } else {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("socket关闭");
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}复制代码

说明一下:该段代码中的2个阻塞点:

  1.  server.accept(),该方法用于获取一个socket,在未接收到客户端连接的时候它会一直阻塞
  2.inputStream.read(bytes),当客户端连接成功后,程序阻塞等待读取数据发送的数据

通过telnet客户端连接

将上述的服务端代码启动起来。


通过telnet去连接 发送数据

然后回车:



看服务端的变化:

这个时候,在DOS窗口,按下Ctrl+】

发送命令:send hello


查看服务端:成功接收到hello


想一下,这个时候在过来一个客户端去连接该服务器。会有什么变化。


重新打开一个DOS窗口


回车:


查看服务端:没有变化



在单线程的io中,在长连接的时候客户端的socket独占线程,这造成其他的客户端连接到该服务端,它也无法获取到socket并进行数据读取。


传统io单线程处理的弊端:一个服务端无法为多个客户端提供服务。

改成多线程为多个客户端处理消息


运行结果:


这样就成功的解决掉了不能为多个客户端服务的问题,但是新的问题就来了,如果来一个客户端,新启一个线程,你的电脑会承受不住的。


由此,对传统IO改进,就有了NIO

NIO和传统IO的区别

NIO被称为非阻塞IO。来看看和传统IO的区别


传统IO:



如果将整个服务端程序看成是一家餐厅的话,serverSocket就是大门,而客人是客户端,服务员就是处理读写操作的线程。传统的处理方式是,当大门(serverSocket),来一个客人(client),餐厅(sever)就为他分配一个服务员(thread),这一个服务员为一名客人服务,这样明显会造成人力浪费,是一种非常不可取的方式。


看看NIO怎么处理:




还是刚才那个餐厅和服务员的比喻。nio新加入了几个概念,一个是channel(通道)相当于socket,一个是selector(多路复用器)。当大门(serverSocketChannel)检测到有新的客人(client)上门的时候,餐厅不再是直接给他派遣一个服务员,而是让他在服务员那里去登记一下(就像我们点餐一样,点好了拿着点餐的牌号,然后等着服务员根据订单给你上菜就好了),然后由一个服务员根据你登记的需要服务的事项(在nio中成为状态)为所有客人服务。这样一个服务端就可以为多个客户端提供服务了,大大的节约了资源。


关注51码农网,寻找一起进步的同学。www.51manong.com

51码农网  程序员社群学习打卡集聚地

关注51码农网官方微信公众号:

转载于:https://juejin.im/post/5c779b22e51d4517674d28c1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值