首先,我们要先对这几个概念有一个直观的理解,对于初学者来说,你可以这样看待这几个概念:
举个例子 小明领着女朋友去超市购物,买了很多东西,当他走到收银员那里结账的时候,小明(
客户端)发出了要求结账的讯息(
请求),收银员(
服务器)会对他这一要求进行处理。此时有可能产生多种场景
- 小明傻傻地等着收银员用计算器算出所有物品的总价,并准备付款。(同步阻塞:小明在请求响应之前,一直在等待;收银员没有做别的事情,一直在处理小明的请求)
- 小明觉得自己太傻了,于是一边和女朋友聊天,一边催促收银员快点计算出总价。(同步非阻塞:小明在请求响应之前,做了其他的事情;收银员一直在处理小明的请求)
- 小明傻傻地等着收银员的总价结果,收银员却把计算的工作交给计算机之后就去拿袋子帮忙装东西,直到计算机上出现了总价结果,收银员才继续回来完成收款工作。(异步阻塞:小明在请求响应之前,一直在等待;收银员在处理小明请求的过程中,处理了其他的事情)
- 小明觉得自己太傻了,于是一边和女朋友聊天,一边催出收银员快点计算出总价,而收银员却把计算的工作交给计算机之后就去拿袋子帮忙装东西,直到计算机上出现了总价结果,收银员才继续回来完成收款工作。(异步非阻塞:小明在请求响应之前做了其他的事情;收银员也在处理请求的过程中,处理了其他的事情)
- 阻塞,非阻塞,指的是小明是否在等待处理结果的过程中去做了其他的事情。
- 同步,异步,指的是收银员是否在处理收款这一请求的过程中去做了其他的事情,这也导致了收款的结果是当时告诉了小明,还是之后又进行了额外的通知。
- 老张把水壶放到火上,立等水开。(同步阻塞)老张觉得自己有点傻
- 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的响声。
- 老张把响水壶放到火上,立等水开。(异步阻塞)老张觉得这样傻等意义不大
- 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)
- 所谓同步异步,只是对于水壶而言。
- 普通水壶,同步;响水壶,异步。
- 虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。
- 同步只能让调用者老张去轮询自己(情况2中),造成老张效率的低下。
- 所谓阻塞非阻塞,仅仅对于老张而言。
- 立等的老张,阻塞;看电视的老张,非阻塞。
- 情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。
- 同步阻塞:在此种方式下,用户进程在发起一个IO请求以后,必须等待IO请求的返回,只有当IO请求返回以后,用户进程才能继续运行。JAVA传统的IO模型(BIO)属于此种方式。
- 同步非阻塞:在此种方式下,用户进程发起一个IO请求以后便可以返回做其它事情,但是用户进程需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的CPU资源浪费。其中目前JAVA的NIO就属于同步非阻塞IO。
- 异步非阻塞:此种方式用户进程发起一个IO请求后,便返回做其他事情,而真正处理IO的应用发起一个IO操作以后,不等待内核IO操作的完成,也可以处理其他事情,等内核完成IO操作以后会通知处理IO的应用,处理IO的应用再通知用户进程。目前JAVA中的AIO就属于异步非阻塞IO。
- AsynchronousSocketChannel
- AsynchronousServerSocketChannel
- AsynchronousFileChannel
- AsynchronousDatagramChannel