IO模型
简单地理解,IO模型就是用什么样的通道进行数据的发送和接收,IO模型很大程度上决定了程序通信的性能
java共支持三种网络编程模型:BIO、NIO、AIO
BIO
同步并阻塞(blockingIO),服务端实现模式为一个连接一个线程,即一个客户端请求服务端就需要启动一个线程来进行处理,并且这个线程在读数据时会堵塞,具体跟accept()和read()方法有关。下面直接上代码讲解
注:所谓的同步,就是指所有操作都由当前线程来处理,亲力亲为。而异步呢,是指将操作交由其它线程来处理,其它线程处理完毕之后,返回处理的结果
代码
服务端代码
1 | csharp复制代码public class BIOserver { |
客户端代码
1 | ini复制代码public class BIOclient { |
运行
先启动服务端,可以看到,服务端启动后就阻塞在accept()方法上,等待客户端的连接。如果没有连接,则会一直阻塞
紧接着,我们打上断点,启动客户端来建立与服务端的连接。如下,可以看到,建立完连接之后,服务端阻塞在read()方法上,等待读取数据。如果客户端没有发送数据,则thread-1会一直阻塞在read()上
接着让客户端断点往下走,则服务端读取到数据,打印出来
我们再启动一个客户端,继续上面的流程。可以看到,这时候创建了一个新的线程thread-2,如果我们启动100个客户端,那么服务端自然也就要创建100个线程来处理客户端的请求咯
分析
从上面的分析可以看到,在accept()等待连接时会阻塞,在read()等待读取数据时也会阻塞,所以我们必须对每个客户端创建一个线程,否则accept()的阻塞会影响到对其它客户端的读操作。
一个连接就要创建一个线程,10万个连接就要创建10万个线程,这样显然是不合理的,因为服务器没有那么多的资源来分配给线程。另一个方面,如果建立连接之后,线程没有数据可读,那么就会阻塞在read操作上,造成线程资源的浪费。
其实整个问题的根源就在于accept()和read()的阻塞,也就是所谓优化点,接下来我们引入NIO
NIO(未完待续)
NIO,即non-blocking IO,同步非阻塞IO,是指从JDK1.4开始,java提供的一系列改进的输入/输出新特性,NIO也称为new IO。NIO的三大核心部分分别为:Channel、Buffer和Selector
流
对于所谓的IO流,刚开始学习java IO时我一直都无法理解,为什么要叫IO流呢?后面不断深入学习才开始理解
要理解IO流,我们可以通过水流来类比。在生活中,水流通常是从供水站经过水管输送到居民家中,我们可以把IO流比作水管,传输的数据比作水管中的水,数据源和数据接收方则分别对应供水站和居民。
而所谓的输入、输出流呢,其实都是相对于当前主机的内存而言的。如果把数据从磁盘或网卡输入到内存,那么就要使用输入流;如果把数据从内存输出到网卡或者磁盘,那么就要使用输出流。即,输入内存用输入流,输出内存用输出流!
明天继续更新……
本文转载自: 掘金