- Java中的IO分为:
- BIO:BlockingIO,同步式阻塞式IO,即传统的IO,是Java中最早期的流
- NIO:Non-BlockingIO,又称New IO,同步式非阻塞式IO,是JDK1.4提供的流
- AIO:AsynchronousIO,异步式非阻塞式IO,可以认为是NIO的二代版本,是JDK1.8提供的流
- 简述同步IO、异步IO、阻塞式IO、非阻塞式IO 简述同步IO和异步IO的区别
- 总结:
- 非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
- 阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,cpu不会给线程分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回。有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回,它还会抢占cpu去执行其他逻辑,也会主动检测io是否准备好。
- 异步和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。Ajax请求(异步):请求通过事件触发——>服务器处理(这时服务器可以做别的事情)——>处理完成
- 同步就是发出一个任务,这个任务没得到结果之前,不返回任何结果,直到得到结果结束以后才能做下一个任务。做完一件事情才做下一件事情。B/S模式属于同步:提交请求——>等待服务器处理——>处理完毕返回,在这个期间之内浏览器不能做任何事情。
- 总结:
1. 同步,就是我调用一个功能,该功能没有结束前,我死等结果。
2. 异步,就是我调用一个功能,不需要知道该功能结果,该功能有结果后通知我(回调通知)。
3. 阻塞,就是调用我(函数),我(函数)没有接收完数据或者没有得到结果之前,我不会返回。
4. 非阻塞,就是调用我(函数),我(函数)立即返回,通过select通知调用者
同步IO和异步IO的区别就在于:数据拷贝的时候进程是否阻塞
阻塞IO和非阻塞IO的区别就在于:应用程序的调用是否立即返回
综上可知,同步和异步,阻塞和非阻塞,有些混用,其实它们完全不是一回事,而且它们修饰的对象也不相同。
原文链接:
- BIO的缺点
- 一对一的连接方式:即每一个连接请求需要对应一个线程,在请求量大的情况下,会导致服务器端的压力非常大从而致使整个服务器的处理效率变低
- 阻塞:当线程在进行read或者write的时候,除非读完或者写完,否则在这个过程中不能发生任何操作
- 单向传输:数据只能从一端传向另一端,如果需要反向传输需要令创建流对象
- NIO优缺点:
- 在请求量比较大的情况下会出现部分请求的响应时间比较长的现象
- 不适用于长任务场景,不然会导致其他的请求无法处理
- 一对多的连接方式:利用一个或者少量线程处理大量的连接请求,降低服务器端的压力
- 非阻塞:在线程不能进行read或者write方法的时候,立即返回,等待下一次操作
- 双向传输:利用通道可以实现数据的双向
- NIO与BIO的区别
BIO | NIO |
同步阻塞式IO | 同步非阻塞式IO |
单向传输数据 | 双向传输数据 |
面向流操作 | 面向缓冲区操作 |
一对一的连接方式 | 一对多的连接方式 |
适合于请求少,长连接的场景 | 适合于请求多但短连接的场景 |
- Buffer
- 简介:又称之为缓冲区,用于存储数据的容器,本质是一个数组,在内存中占用了一块连续的空间。Java中针对不同的基本类型提供了不同的缓冲区(但需注意的是没有boolean类型对应的缓冲区),其中最基本的字节缓冲区ByteBuffer
- ByteBuffer
- 概述:字节缓冲区,继承了Buffer类,底层是依靠字节数组来存储数据,本身是一个抽象类,需要利用其子类创建对象或者是利用其提供的allocate或者是wrap方法来创建ByteBuffer对象,重要位置capacity >= limit >= position >= mark
- 重要位置
- capacity:容量位。用于标记该缓冲区的容量,在缓冲区创建好之后就不再改变
- limit:限制位。用于限制操作位position所能达到的最大位置。在缓冲区刚创建的时候指向容量位
- position:操作位。用于指向要操作的位置,实际意义类似于数组中的下标。在缓冲区刚创建的时候指向0
- mark:标记位。用于进行标记。在缓冲区刚创建的时候指向-1,默认不启用
- Channel
- 简介:Channel,称之为通道,在NIO中用于完成数据的传输,在操作的时候是面向缓冲区进行的,可以实现数据的双向传输,Channel默认是阻塞的,可以手动设置为非阻塞
- FileChannel:面向文件的通道,可以利用FileChannel完成对文件的操作,利用FileChannel读取文件的时候,是先将文件中的内容映射到虚拟内存中,然后再读取到程序的缓冲区中,FileChannel不能直接创建,可以利用FileInputStream、FileOutputStream、RandomAccessFile对象中的个体Channel()方法获取,通过FileInputStream获取FileChannel,那么只能进行读取操作,FileOutputStream获取FileChannel,那么只能进行写入操作,
- 如果是通过RandomAccessFile获取FileChannel,那么可以进行读写操作
- UDP:用于进行UDP收发的通道,是无连接的网络协议,只能进行发送和接收的操作,基本类是DatagramChannel,是一个抽象类
- TCP:用于进行TCP通信的通道,需要进行连接的网络协议,提供了连接、接收、读取、写入操作,客户端通道是SocketChannel,服务器端通道是ServerSocketChannel
- Seclector,多路复用选择器,对通道进行选择,需要基于事件进行驱动,针对了四类事件:connect、accept、read、write,四类事件定义在SelectionKey中,可以实现利用一个或者少量线程处理大量请求,适用于大量的短任务场景,不适用于长任务场景,Selector针对的必须是非阻塞的通道
- 通信框架:
- Netty概述:Netty是一款异步的事件驱动的网络应用框架和工具,用于快速开发可维护的高性能、高扩展性协议服务器和客户端,Netty是一个NIO客户端/服务器框架,支持快速、简单地开发网络应用,如协议服务器和客户端,它极大简化了网络编程,如TCP和UDP套接字服务器,Netty是完全基于NIO实现的,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果
- Netty优点:API使用简单,开发门槛低,功能强大,预置了多种编解码功能,支持多种主流协议,定制能力强,可以通过ChannelHandler对通信框架进行灵活地扩展,性能高,通过与其他业界主流的NIO框架对比,Netty的综合性能最优,成熟、稳定,Netty修复了已经发现的所有JDK NIO BUG,业务开发人员不需要再为NIO的BUG而烦恼