每天早上七点三十,准时推送干货
Photo by Scott Evans on Unsplash
阿粉第一次了解到io相关知识是在网上看面经的时候,平时只会写业务代码,面对bio,nio,多路复用器这些概念简直是一头雾水。
当阿粉尝试单独去学习这些名词,发现很难学懂,如果能有一篇文章串起来讲讲他们的关系,可能对初学者来说有一定的帮助,所以便有了下面这篇文章。
BIO
BIO即为阻塞IO的意思,通常我们讲BIO的时候都会和服务器模型配合着讲,在实际应用中讲会更好理解。大家看下面的代码,估计在大家初学java网络编程的时候用的都是这个模型:
public static void main(String[] args) throws Exception {
//建立socket,socket是客户端和服务器沟通的桥梁
ServerSocket server = new ServerSocket(9090,20);
//通过死循环不断接收客户端请求
while (true) {
//线程会阻塞在这行的accep方法
Socket client = server.accept();
//创建新线程处理新客户端的逻辑
new Thread(() -> {
//client的读写逻辑
}).start();
}
}
只要没有客户端连接上服务器,accept方法就一直不能返回,这就是阻塞;对应的读写操作道理也一样,想要读取数据,必须等到有数据到达才能返回,这就是阻塞。
我们还可以站在阻塞的基础上思考一下,为什么服务器的模型要设计成来一个客户端就新建一个线程?
其实答案很简单,当来了一个客户端创建连接后,如果不给客户端新分配一个线程执行服务器逻辑,那么服务端将很难再和第二个客户端建立连接。
就算你把客户端连接用集合保存起来,通过单线程遍历集合的方式去执行服务器端逻辑也是不行的。因为如果某个客户端连接因为读写操作阻塞了,那么其他客户端将得不到执行。
NIO
如果说服务器只有很少的人用,那么上面那段bio的代码其实挺好的,但问题在于互联网蓬勃发展,随着服务器访问人数的增加,这样的服务器模型将会成为瓶颈。