netty的原理及使用
阻塞、非阻塞、同步和异步
首先需要明白什么是阻塞、非阻塞、同步和异步
- 阻塞和非阻塞是描述线程的工作方式.
阻塞:
线程在得到结果之前会一直等待结果的返回,期间什么也不干,就像小时候我们向父母讨零花钱,如果不给我们干嘛呢? 在地上撒泼打滚什么也不干.直到父母给了零花钱.这就是阻塞
非阻塞:
线程发起请求之后不会一直等待可以做别的操作,就像跟你好朋友吃饭,你们去的那家点是家网红店需要排队,你们先叫了个号发现前边还有十多个号,你可以在排到你之前去干别的事情,甚至可以先去隔壁买杯喝的.这就叫非阻塞.
- 同步和异步之间是来描述客户端和服务端交互的情况.
同步:
即客户端在请求服务端后是一直等待服务端的返回,在得到服务端的返回结果之前客户端会一直轮询服务端有没有返回.这就叫同步.
异步:
客户端在请求服务端后不在一直轮询服务端是不是有返回,而是由服务端在完成处理后向客户端发起处理完成的信号.
异步通知一般是通过状态改变、消息通知或者回调函数实现.
- I/O操作中同步阻塞、同步非阻塞、异步阻塞、异步非阻塞的属性表
属性 | 同步阻塞I/O | 异步阻塞I/O(伪异步) | 同步非阻塞I/O | 异步非阻塞 |
---|---|---|---|---|
客户端:I/O线程数 | 1:1 | M:N(M>=N) | M:1 | M:0 |
阻塞类型 | 阻塞 | 阻塞 | 非阻塞 | 非阻塞 |
同步 | 同步 | 同步 | 同步(多路复用) | 异步 |
api使用难度 | 简单 | 简单 | 复杂 | 一般 |
调试难度 | 简单 | 简单 | 复杂 | 复杂 |
可靠性 | 非常差 | 差 | 高 | 高 |
吞吐量 | 低 | 中 | 高 | 高 |
什么是BIO什么是NIO
我们都直到netty和NIO有着千思万缕的关系,那什么是NIO呢? 什么又是BIO? 二者又有什么区别?
- BIO和NIO
BIO:同步并且会阻塞,为每一个连接创建一个线程,即客户端有N个连接请求时服务器端就需要N个线程进行处理,就会出现当连接不做任何事情会造成不必要的线程开销,虽然可以通过线程池机制改善。
NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
简而言之:BIO是一个连接用一个线程管理,NIO是一个线程管理多个连接
- 对比
I/O模型 | BIO | NIO |
---|---|---|
通信 | 面向流 | 面向缓冲区 |
处理 | 阻塞I/O | 非阻塞I/O |
出发 | 无 | 选择器 |
面向流、面向缓冲
面向流:
每次中流中读取一个或多个字节,直至读取所有字节,因为没有被缓存在任何地方所以不能前后移动流中的数据,如果需要移动需要先将其缓存在一个缓存区.
面向缓冲区:
数据读取到一个稍后处理的缓冲区,需要时可在缓冲区前后移动,增加了数据处理的灵活性,但需要检查缓冲区是否包含所有所需要的数据,
并且需要确保新读入的数据不会覆盖缓冲区中未处理的数据
阻塞、非阻塞
由前边的阻塞和非阻塞,同步和异步可以明白二者区别
阻塞:当BIO调用read()或这write()是,该线程被阻塞,直到有部分数据被读取,或者全部读取.
非阻塞:NIO的非阻塞模式,是一个线程从某通道发送请求读取数据,它仅能读取目前可用的数据,如果没有数据就不会读取,而不是保持线程阻塞.在数据变为可读取之前该线程可以做其他事情.同样的写操作同理
选择器:NIO得到选择器允许一个单独的线程监视多个通道,当通道里有可以处理的输入(读)或者有已准备写入通道,就会使一个单独的线程来选择(使用)通道. 这种选择机制可以使用一个线程就能管理多个通道
不论是BIO还是NIO他们都是同步的I/O模式,区别在于BIO是阻塞的而NIO是 非阻塞的