同步和异步,阻塞和非阻塞:
同步和异步其实指的是,请求 发起方 对信息结果的获取是主动发起的,还是等被动通知的。
如果是请求方主动发起的,一直在等待应答结果。(同步阻塞)
如果是请求方发起的,提交请求后去处理其他的事情,但要不断的轮询查看发起的请求是否有应答结果(同步非阻塞)
如果是由服务方通知的,即请求方请求后要么一直等待通知(异步阻塞),要么去忙自己的事了(异步非阻塞),当请求有结果,服务器主动通知请求方。
总结:
同步和异步,阻塞和非阻塞 :
同步和阻塞不是一回事,考虑的角度不一样,同步和异步是对服务提供方来讲的,阻塞和非阻塞是对服务消费方或者请求方来讲的。等待即挂起。阻塞和非阻塞通常指请求方在发送请求后,在服务器处理请求的过程中,请求方是挂起等待结果,还是继续做其他事情。而异步和同步则是指对于请求结果的获取是请求方主动获取,还是服务器来推送请求结果。
小米找领导请假,有4种模式:
①同步阻塞:小米把假条给领导,然后在办公室里死等领导签完字。
②同步非阻塞:小米把假条给领导,然后去敲代码,隔一段时间就去办公室问下领导是否签完字了。
③异步阻塞:小米把假条给领导,然后领导说:你先出去到办公室门口等着,我签完字叫你(貌似没必要等着)。
④异步非阻塞:小米把假条给领导,然后领导说:你去敲一会代码,我签完字叫你。
请求方请求后等待结果 | 请求方请求后不等待(轮询结果) | |
---|---|---|
请求方主动要结果 | 同步阻塞① | 同步非阻塞② |
服务器通知请求方结果(回调函数) | 异步阻塞③(貌似没必要) | 异步非阻塞④ |
异步时,服务器通知请求方结果的方式一般是通过状态改变,消息通知或者回调函数完成,大多数都是回调函数。
BIO,NIO(摘抄自:https://www.jianshu.com/p/a4e03835921a)
在传统的BIO模型中,每个socket连接创建成功后都需要一个线程来维护,每个线程包含一个while死循环,如果有1w个连接则对应1w个线程,继而1w个死循环,会带来如下问题:
1、线程资源受限:线程是操作系统中非常宝贵的资源,同一时刻有大量的线程处于阻塞状态是非常严重的资源浪费,操作系统耗不起;
2、线程切换效率低下:单机CPU核数固定,线程爆炸之后操作系统频繁的进行线程切换,应用性能急剧下降。
IO编程模型在客户端较少的情况下运行良好,但是对于客户端比较多的业务来说,单机服务端可能需要支撑成千上万的连接,IO模型可能就不合适了。
NIO的核心思路:
1、NIO模型中(服务端)通常会有两个线程,每个线程绑定一个轮询器selector。其中serverSelector负责轮询是否有新的连接,clientSelector负责轮询是否有数据可读。
2、服务端监测到新的连接后,不再创建一个线程,而是直接将新连接绑定到clientSelector上,这样就不用IO模型中1w个while循环在死等。
3、clientSelector被一个while循环包裹着,如果在某一时刻有多条连接有数据可读,那个通过clientSelector.select(1)方法可以轮询处理,进而进行批量处理。
4、数据的读写以内存块为单位。
Netty(摘抄自:https://www.jianshu.com/p/a4e03835921a)
NIO编程复杂,NIO没有实现一个合适的线程模型,需要自己实现,自行实现的NIO很容易出现各类BUG,犹如带刺的玫瑰
正因为如此,Netty横空出世。Netty封装了JDK的NIO,Netty是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能服务器和客户端。
选择Netty不选择NIO的原因:
1、使用jdk自带的NIO需要了解很多概念,编程复杂
2、Netty底层的IO模型可以随意切换,修改参数,Netty可以直接从NIO模型变为IO模型
3、Netty自带的拆包解包,异常检测等机制让你从NIO的繁重细节中解脱出来,让你只需要关心业务逻辑
4、Netty解决了JDK的很多BUG,包括空轮询在内.
... ....