同步:调用接口数据,实时返回接口数据。也就是发送一个请求,需要等待返回,才能发送下一个请求,在这等待过程中,你不能做其他的操作,只能等着。可以避免死锁,但所有的操作都做完,才返回给用户,用户等待时间过长,给人一种卡死的感觉,若关闭了页面,程序就中断了。白话文:边吃边拉-实时性
异步:调用接口数据,服务方发送一个成功的状态后结束,然后服务方准备数据后,主动作为调用方将数据推送给你。也就是发送一个请求,不需要等待返回,就能随时发送下一个请求。即:将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了,然后程序再慢慢地去写入数据库去-先将数据放放消息队列,再慢慢写入数据库。如ajax的实现局部更新的效果就是异步通信。白话文:吃完了再拉
同步通讯:如打电话,需要实时响应。这一过程中不能做别的事。
如:feign调用,可以实时得到结果
异步通讯:就像发邮件,不需要马上回复。在这过程中,你还可以去做别的事
如:ajax,可以实现局部刷新--不用更新整个页面
两种方式各有优劣,打电话可以立即得到响应,但是你却不能跟多个人同时通话。发送邮件可以同时与多个人收发邮件,但是往往响应会有延迟。
同步和异步是编程技术的特性,可以通过这些特性构成阻塞和非阻塞模型
阻塞就好比你喊我,你会一直等到我做出应答后,你才会继续往下工作
非阻塞相当于你喊我,你不会一直等我做出响应,你也可以继续往下工作。
实现这些模式需要借助同步和异步技术
JAVA的通信
BIO、NIO、AIO
在Java的软件设计开发中,通信架构是不可避免的,在进行不同系统或不同进程之间的数据交互,或在高并发的通信场景下,都需要用到网络通信相关的技术,如实现不同通信系统之间的数据交互,或者在做网游的服务器时,需要解决不同玩家之间数据的交流、信息的存储等
BIO、NIO、AIO是不同数据交流模式下的技术,它最终与通信结合后,可以解决局域网内的通信要求,如一家公司内部的通信需求;多系统间底层消息传递机制,也就是说多个系统之间信息的交流;高并发下大数据量的数据通信场景需要,它的底层也是基于BIO、NIO、AIO一些技术的影子作为它的基础,尤其是游戏行业,无论是手游服务器、还是大型网络服务器,都会用到网络通信的技术,即使用较为高级的网络通信技术,它的底层也会有这些通信模式的影子
对于一些经验丰富的程序员来说,java早期的网络通信技术存在一些缺陷,最令人烦恼的是基于性能低下的同步阻塞式的IO通信--BIO
BIO:同步阻塞式IO,它的底层是基于IO流来进行数据的读写,性能低。它是一个连接一个线程,客户端越多,服务端就会创建更多的线程,且每个线程都需要与客户端进行同步阻塞,当客户端没有数据时,服务端线程也需要进行等待,就造成了不必要的线程开销,且可能会引起宕机,也可以通过线程池来改进这种架构,但当并发量特别大时,它依然存在很大的性能局限
应用场景:数量比较小,架构比较固定,对于客户端的需求没有那么高的要求,或客户端数量比较少,可选择BIO模式。比较直观,且较为简单
随着互联网开发下通信系统的高要求,尤其是在高并发的场景下,原始的BIO模式并不能够完成高性能的数据读写,java在2002年开始支持非阻塞式的IO通信--NIO
NIO:同步非阻塞式IO,它底层是基于缓冲区的方式来进行数据的读写的。它的服务器模式为一个请求一个线程,当服务器使用一个线程来维护一个多路复用器或选择器时,可以把客户端的通道请求都注册到这个选择器,由选择器来轮询客户端的通道,当通道有数据时,才进行处理,如果通信没有数据,就不用理会。这种模式可以实现单个线程就能处理大量通道信息的情况,对于比较高性能要求的通信模式,应该选择基于NIO来进行开发
NIO的编程在开发中比较复杂,尤其是用它来做大型服务器,前期的成本很高,Java的NIO编程虽然提高了性能,但实际使用更加高级的如netty框架,来对NIO的代码进行包装更好。
应用场景:连接数量多,操作尽量比较短(连接比较短),因为它是轮询的方式来处理的,如果通道的数据过多,它就会长期占用这个当前线程,导致它的整体性能降低。编程比较复杂,从JDK1.4才开始支持
如聊天服务器,它的连接特别多,有非常多的客户端在请求,但每个消息很短,使用NIO就很合适
AIO是NIO 2.0的一个版本
AIO:异步非阻塞式IO,服务器模式为一个有效请求一个线程,它的操作是由底层操作系统帮助完成后,通知程序进行操作,这样能更多的优化性能。编程比较复杂,JDK7才开始支持
应用场景:连接数量多,操作比较长(连接比较长),它有轮询的机制,但是它底层数据的读写是由操作系统维护的,当数据量多的情况下,使用AIO更为合适,它底层的操作系统可以慢慢的去加载通道的数据,服务端这边也没有过多的线程,这种架构相对比较完美,可以做类似于相册服务器,它的连接比较多,数据量也比较大,就可以充分调用操作系统参与并发,
对于通信场景要求比较高的情况下,可以采用这些模式的类似于netty这样的网格编程框架来解决
实际上不会用太多的NIO技术去解决各种通信服务器的需求,因为要投入很大的成本去开发NIO这样的服务器,要很长的时间,开发出来后,也可能会产生很多bug,因为NIO的编程比较复杂,且在后续的维护中都会是一件比较痛苦的事情,会产生大量的成本和系统开发的风险。基于BIO、NIO、AIO的演变会是一个类似于netty这样的网络编程框架