面试时一个高频问题就是bio,nio与aio,今天我们就来聊一聊BIO。
BIO的B指的是block(阻塞)。根据发出IO请求是否会阻塞线程,我们将IO划分为阻塞和非阻塞式IO。
以网络聊天室功能的实现为例,BIO的实现过程为:
在服务端起一个ServerSocket,并调用ServerSocket的accept方法等待客户端连接(这里的accept方法是阻塞的,没有客户端连接过来会一直阻塞线程)。
在客户端起一个socket与服务端建立连接后服务端会从阻塞状态唤醒,服务端程序可以继续运行。
服务端获取了一个客户端的连接后可以拿到与客户端的通道,客户端服务端可通过此通道进行信息发送。服务端用getInputStream方法可以获取到客户端发送来的数据。(此方法是阻塞的,客户端没有发送信息时会一直阻塞)。
同样的客户端也可以通过getInputStream方法可以获取到服务端发来的数据,同样是阻塞的。
如此,客户端和服务端之间建立了连接,并且可进行信息交互,一个基本的网络通讯功能就实现了。代码实现也非常的简单,服务端加客户端代码量不会超过100行,可自行百度。
总结以上过程不难发现,虽然实现了网络通讯的基本功能但有以下缺点:
1、整个实现过程有大量的阻塞,IO通讯过程效率非常低
2、服务端每次只能服务一个客户端,这个点可以优化为:在每一个客户端连接进入服务端时,将服务端与客户端建立的连接放入一个新建的线程中,这样就可以同时处理多个连接请求了,但是每个socket连接都需要新起一个线程来对应此连接,非常占用资源,在几十年前并发量较低时还行,但在当前高并发的情况下尤显无力。
形象比喻的话就是:我们去饭店吃饭,从进了饭店门开始饭店就让一个服务员跟着我们,我们所有的要求直接和这个服务员说,服务员处理完成我们的要求,即使我们没有事要服务员去做,服务员也会站在我们旁边等待我们的指令,直到把我们服务完,送出饭店为止。