引言
这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战
今天我们介绍一下经典的IO模式以及Netty是如何实现的。
经典的IO模式
- BIO(阻塞IO),JDK1.4之前
- NIO(非阻塞IO),jDK1.4
- AIO(异步IO),JDK1.7
IO模型的特点
- 阻塞:如果没有数据传过来时,读会阻塞,当缓冲区的数据满时,写会阻塞。
- 非阻塞:直接返回。
- 同步:读操作由谁来完成,如果由用户进程来完成就是同步
- 异步:不需要用户进程去读取数据,
Netty支持的IO模式
Netty仅仅支持NIO,对于BIO,由于BIO是同步阻塞的,这就造成线程拿不到数据时,就只能阻塞,如果此时有大量请求进来,就只能等待,占用的系统资源不能释放,就会使资源耗尽。
对于AIO,虽然Windows系统成熟,但是不能用来做服务器,而Linux上的AIO还不够成熟,相比NIO的性能提升也不够明显。
Netty的多种NIO的实现
Netty的NIO都是自己实现的,Netty觉得自己实现会更好:
- Netty暴露了更多的可控参数:JDK的NIO默认是水平触发,Netty默认是边缘触发和水平触发可切换。
- Netty实现的垃圾回收性能更好
BIO的优势:BIO代码简单,适合连接数少,并发度低的场景。
Netty的多种IO的模式切换解析
这里,我们直接上代码,对于服务器开发,如果要切换IO模式,首先切换的就是EventLoopGroup,这是其对应的开发模式,接着切换IO模式就是对应的Channel。
接着我们点进Channel方法去看一下:
这里我们上面传的是NioServerSocketChannel.class,而形式参数是一个clazz对象,也就是说我们即可以传BioServerSocketChannel.class,也可以传其它Channel,然后我们看方法里面做了什么:
方法内部做了一个判断,new了一个ReflectiveChannelFactory,可以看出这是反射的工厂对象,点进去看内部实现:
这里是反射调用了对象的构造方法,用于创建对象:
然后,创建好的对象就是我们的NioServerSocketChannel实例了,这种实现是泛型加反射加工厂的实现模式。