NIO学习笔记,从Linux IO演化模型到Netty—— 究竟如何理解同步、异步、阻塞、非阻塞
我的观点
首先,分开各自理解。
1. 同步:描述两个(或者多个)个体之间的协调关系。
比如,单线程中,methodA调用了methodB,methodB返回后,methodA才往下执行,那么称A同步调用了B。
比如,多线程中,线程1访问完某个资源,才到线程2访问。
同步在一定的 互斥基础上,强调的是有序性。(另外,互斥强调的是排他性,我在用的时候你不许用。)
2. 异步:我觉得是指个体之间并没有协调关系,你走你的阳关道,我走我的独木桥。
比如,线程往线程池里面提交了FutureTask,就继续往下执行,A叫B帮自己倒杯咖啡,而A自己干别的事去了。
阻塞与非阻塞,都是线程或进程的状态。
3. 阻塞:线程或进程被挂起,失去了cpu的使用权。
4.非阻塞:就正常运行下去。
非要把两种概念扯起来理解是没必要的,对于发生的一件事,从两种不同的角度去理解即可,如果非要根据这两种概念去造出一件事,那么很可能自己会混淆(易混淆的一个点为,同步和阻塞在某种层面上表现为“等”),而且这件事还不对。
比如 BIO中的accept(),调用时线程会一直阻塞,失去cpu的使用权直到有人连上来,这时候,假如线程又回到运行态,如果不去读取出来,后面的人还连不上。
(注意线程每次系统调用时,要从用户态切换到内核态)
到这里相信已经这几个概念已经比较清晰了,还要说什么同步阻塞,同步非阻塞?
所见网上的例子,我认为这样理解是不恰当
老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
1 老张把水壶放到火上,立等水开。(同步阻塞)
老张觉得自己有点傻
2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。
3 老张把响水壶放到火上,立等水开。(异步阻塞)
老张觉得这样傻等意义不大
4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)
我只分析第4点这里,响了再去拿壶。
但是老张如果没有一直在听的话又怎么知道它响没响呢?是不是可以把一直在听也看作是一种轮询呢?那这样的话又和同步非阻塞的例子有什么不同呢?这绝不是找茬,因为谁通知谁,怎么通知的,怎么接收通知的,这很重要!
其他的例子更是漏洞百出。
我就说扯起来讲没必要吧。
我的例子
如果你真的要等某件事发生才能往下执行的话(同步),那你就应该阻塞等它完成(免得你一直问一直问,浪费资源)。如果你非阻塞,还不一直问他就执行往下执行干其他事去,那说明你并不是非等他完成不可,那何不等你真的要依赖他的时候再阻塞等候呢。
而异步说明这两个人没有关系,你做你的(你可以睡一觉阻塞,也可以不阻塞),他做他的。