基本概念
分类:
BIO:(同步 阻塞)jdk1.4以前 java.io包
NIO:(同步 非阻塞)jdk1.4 java.nio包
AIO:(异步 非阻塞)jdk1.7 java.nio包
概念:
1.阻塞、非阻塞:程序等待消息通知的角度
调用系统方法,阻塞就是被挂起,非阻塞是直接返回。
2.同步、异步:消息通知的角度
主动获得消息,还是被动接收消息
如:人------>银行 ,人在银行排队
阻塞:排队时你不能干别的。
非阻塞:等待时玩手机。
同步:排队抬头看到了没。
异步:银行通知你到了。
两两组合。
2)使用场景:
BIO:连接数少
NIO:连接数多,连接时间短
AIO:连接数多,连接时间短
1.BIO
1.服务端循环等待,一个客户端连接,就创建一个线程。
·
如:java中,创建一个ServerSocket,然后serverSocket.accept()循环等待客户端连接,但是在这一操作时是阻塞等待的。
注意:
socket:套接字=ip:port
客户端可以使用telnet或者ssh
·
2.NIO(核心:IO多路复用)
三大核心组件:Buffer,Channel,Selector
BIO 到NIO的演进(重要)
1.一个server一个线程,处理一个请求
·
2.一个server开启多个线程处理多个线程
·
3.基于(2)使用线程池
·
4.nio包允许开启非阻塞(直接返回结果)
·
5.基于(4)开启同步循环检测
注意:虽然此时是非阻塞模式了,但是while循环,却始终保持cpu的高度占用,所以之后引入了selector,基于事件发生。
如下图:
·
6.加入selector,实现io多路复用
bio特点
1.阻塞的
2.面向流的操作,一个字节一个字节效率低
nio特点
1.serverSocketchannel可以选择非阻塞
2.面向buffer,效率高
3.selector可以实现io多路复用,当然这要基于非阻塞才可以
注意:nio强于bio的点在于不用大量的线程切换,也就是核心:io多路复用
场景
1.像mysql这些性能卡在磁盘io上的,提高连接数,并不一定提高性能
2.像redis在内存中操作,没有磁盘io性能上的限制,那么网络io就是其性能瓶颈,io多路复用就可以实现更多连接数,实现性能提升
注意:redis官方版本只有linux的,因为操作系统epoll操作,不是全部遍历,所以db一般不用nio,必要性不高
`
零拷贝
【linux】图文并茂|彻底搞懂零拷贝(Zero-Copy)技术
演进(如下四图)
1.对应java的堆内存分配,该内存在jvm中
2.对应java的直接内存分配,直接使用的内核区。
注意:磁盘到内核使用DMA硬件不需要cpu,以上都需要bytebuffer保存
3.linux2.1 底层sendfile(),java的transeferTo方法,不需要中间的bytebuffer。
4.linux2.3 底层sendifile(),java的transeferTo,直接将内核到网卡。
·
零拷贝作用:
1)减少数据的冗余
2)减少用户态和内核态的切换次数
3.AIO
基于上面异步和非阻塞的案例
例:银行排队,拿着票子就行,你可以玩手机(非阻塞),银行通知轮到你了(异步)
为什么netty5的AIO不使用了呢?
答:因为linux2.6推出的异步api本质还是使用多路复用模拟的,性能没有显著提升,并且还增加了复杂度。