最近在复习java基础的时候,虽然看了好几次同步、异步、阻塞与非阻塞的相关知识点,但过了几天还是会傻傻分不清楚,所以记录一下印象会深刻一点,也把相关知识做个总结。
首先来说一下最不好区分的点,同步、异步和阻塞、非阻塞的区别:
同步、异步:指的是应用层与内核的交互方式(接收数据的方式,同步:主动,异步:被动)
1.同步:应用层不断轮询内核是否准备好数据,准备好则从获取数据
2.异步:应用层发起请求后不主动请求数据,而是被动地等待内核准备完数据后进行通知
阻塞、非阻塞:指是否立马返回结果(不一定)
阻塞:不立即返回结果,期间线程挂起(执行者等待)
非阻塞::立即返回结果(执行者不等待)
同步异步应该比较好理解,但是加上阻塞和非阻塞就很容易弄混,这里有个概念很重要,同步异步说的是返回数据(执行完的数据,比如执行1+1,2就是数据),而阻塞和非阻塞说的是返回结果(请求的应答,可以是2,也可以是“计算进行中”),举个例子。
我们写了个方法计算1+1的方法
同步阻塞:
发起请求,由于是同步,向系统进行轮询是否有结果,第一次询问后,系统没有准备好,由于是阻塞模式,所以没有立即响应请求,而是准备好数据后再返回数据,此过程中线程挂起(由于是阻塞),实际上是发起一次请求一次应答。
同步非阻塞:
发起请求,由于是同步,向系统进行轮询是否有结果,第一次询问后,系统没有准备好,由于是非阻塞模式,所以返回了我还没有准备好的这个结果,经过多次询问后,系统准备好了数据,并返回了数据2(1+1),此过程中线程没有挂起,而是一直再轮询,实际上是发起多次请求多次应答。(一般不用,由于还需要不断轮询消耗性能,效率比同步阻塞还低)
异步阻塞:
发起请求,由于是异步,线程向系统发起一次请求之后立刻被告知数据还没有准备好(异步),然后线程挂起(阻塞),准备好数据后通知线程数据结果(异步),实际上是发起一次请求一次应答。
异步非阻塞
发起请求,内核返回结果告诉线程数据还没准备好,然后线程干自己的事儿去了,等有数据结果2(1+1)了,内核就通知线程结果,一次请求一次应答。
PS:I/O多路复用