同步&异步其实是处于框架这种高层次维度来看待的,而阻塞&非阻塞往往针对底层的系统调用方面来抉择,也就是说两者是从不同维度来考虑的。
同步和异步
同步和异步指的是:当前线程是否需要等待方法调用执行完毕。
同步(Synchronous) :
- 同步操作是按顺序执行的,一个任务执行完毕后,才能开始执行下一个任务。
- 在同步模型中,调用者通常会等待被调用函数完成,然后才能继续执行。
- 同步操作通常用于简单、线性的任务,易于理解和调试。
异步(Asynchronous) :
- 异步操作是不按顺序执行的,一个任务开始后,调用者可以继续执行其他任务,而不必等待当前任务完成。
- 在异步模型中,通常会使用回调函数、事件处理器或者异步API来处理异步任务的结果。
- 异步操作通常用于复杂、耗时的任务,可以提高程序的性能和响应性。
阻塞和非阻塞
阻塞和非阻塞指的是:当前接口数据还未准备就绪时,线程是否被阻塞挂起
阻塞(Blocking) :
- 在阻塞模式下,当程序执行某个操作时,如果该操作需要一段时间才能完成,程序会暂停执行,此时处于挂起状态,一直等待操作完成,然后再继续执行后续代码。
- 在阻塞模式下,程序会被“阻塞”,无法同时执行其他任务,直到操作完成或超时。
非阻塞(Non-blocking) :
- 在非阻塞模式下,程序执行某个操作时,不会等待操作完成。它会立即返回,继续执行后续代码,不会被操作的执行时间所阻塞。
- 在非阻塞模式下,程序可以同时执行其他任务,不必等待长时间的操作完成。
这四个概念两两组合,会形成4个新的概念,如下:
同步阻塞:客户端发送请求给服务端,此时服务端处理任务时间很久,则客户端则被服务端堵塞了,所以客户端会一直等待服务端的响应,此时客户端不能做其他任何事,服务端也不会接受其他客户端的请求。这种通信机制比较简单粗暴,但是效率不高。
同步非阻塞:客户端发送请求给服务端,此时服务端处理任务时间很久,这个时候虽然客户端会一直等待响应,但是服务端可以处理其他的请求,过一会回来处理原先的。这种方式很高效,一个服务端可以处理很多请求,不会在因为任务没有处理完而堵着,所以这是非阻塞的。
异步阻塞:客户端发送请求给服务端,此时服务端处理任务时间很久,但是客户端不会等待服务器响应,它可以做其他的任务,等服务器处理完毕后再把结果响应给客户端,客户端得到回调后再处理服务端的响应。这种方式可以避免客户端一直处于等待的状态,优化了用户体验,其实就是类似于网页里发起的ajax异步请求。
异步非阻塞:客户端发送请求给服务端,此时服务端处理任务时间很久,这个时候的任务虽然处理时间会很久,但是客户端可以做其他的任务,因为他是异步的,可以在回调函数里处理响应;同时服务端是非阻塞的,所以服务端可以去处理其他的任务,如此,这个模式就显得非常的高效了。
BIO,NIO和AIO
BIO(Blocking I/O) 同步并阻塞 ,服务器实现一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,没处理完之前此线程不能做其他操作(如果是单线程的情况下,我传输的文件很大呢?),当然可以通过线程池机制改善。
BIO方式 适用于连接数目比较小且固定的架构 ,这种方式对服务器资源要求比较高,并发局限于应用中JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO(Non-blocking I/O) : 同步非阻塞 ,服务器实现一个连接一个线程,即客户端发送的连接请求都会注册到多路复用器上,多复用器轮询到连接有I/O请求时才启动一个线程进行处理。
NIO方式 适用于连接数目多且连接比较短(轻操作)的架构 ,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4之后开始支持。
AIO(Asynchronous I/O) : 异步非阻塞 ,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由操作系统先完成了再通知服务器应用去启动线程进行处理,AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用操作系统参与并发操作,编程比较复杂,JDK1.7之后开始支持。
AIO属于NIO包中的类实现,其实 IO主要分为BIO和NIO ,AIO只是附加品,解决IO不能异步的实现在以前很少有Linux系统支持AIO,Windows的IOCP就是该AIO模型。但是现在的服务器一般都是支持AIO操作
区别
- BIO是阻塞式I/O,每个I/O操作都会阻塞线程。
- NIO是非阻塞I/O,使用多路复用器来管理多个通道,可以在一个线程中处理多个连接。
- AIO是异步I/O,允许应用程序启动I/O操作后继续执行其他任务,操作完成后得到通知