1. 同步阻塞: 客戶端發送請求給服務端,此時服務端處理任務時間很久,則客戶端則被服務端堵塞了,所以客戶端會一直等待服務端的響應,此時客戶端不能做事,服務端也不會接受其他客戶端的請求。這種通信機制比較簡單粗暴,但是效率不高。
2. 同步非阻塞: 客戶端發送請求給服務端,此時服務端處理任務時間很久,這個時候雖然客戶端會一直等待響應,但是服務端可以處理其他的請求,過一會回來的。這種方式很高效,一個服務端可以處理很多請求,不會在因爲任務沒有處理完而堵着,所以這是非阻塞的。
3. 異步阻塞: 客戶端發送請求給服務端,此時服務端處理任務時間很久,但是客戶端不會等待服務器響應,它可以做其他的任務,等服務器處理完畢後再把結果返回,客戶端得到回調後再處理服務端的響應。這種方式可以避免客戶端一直處於等待的狀態,優化了用戶體驗,其實就是類似於網頁裏發起的ajax異步請求。
4. 異步非阻塞: 客戶端發送請求給服務端,此時服務端處理任務時間很久,這個時候的任務雖然處理時間會很久,但是客戶端可以做其他的任務,因爲他是異步回調函數裏處理響應;同時服務端是非阻塞的,所以服務端可以去處理其他的任務,如此,這個模式就顯得非常的高效了。
以上四點,除了第三點,其餘的分別爲BIO/NIO/AIO,面試官如果問你 “請簡述一下BIO/NIO/AIO之間的概念與區別” ,那麼你就可以組織一下語言來回答
下生活實例來闡述也是可以的:
1. BIO: 我去上廁所,這個時候坑位都滿了,我必須等待坑位釋放了,我才能上吧?!此時我啥都不幹,站在廁所裏盯着,過了一會有人出來了,我就趕緊蹲上。
2. NIO: 我去上廁所,這個時候坑位都滿了,沒關係,哥不急,我出去抽根菸,過會回來看看有沒有空位,如果有我就蹲,如果沒有我出去接着抽菸或者玩會手機。
3. 異步阻塞: 我去上廁所,這個時候坑位都滿了,沒事我等着,等有了新的空位,讓他通知我就行,通知了我,我就蹲上去。
4. AIO: 我去上廁所,這個時候坑位都滿了,沒事,我一點也不急,我去廁所外面抽根菸再玩玩手機,等有新的坑位釋放了,會有人通知我的,通知我了,我就來了。
從這個生活實例中能可以看得出來:
同步 就是我需要自己每隔一段時間,以輪訓的方式去看看有沒有空的坑位;
異步 則是有人拉完茅坑會通知你,通知你後你再回去蹲;
阻塞 就是在等待的過程中,你不去做其他任何事情,乾等着;
非阻塞 就是你再等待的過程中可以去做其他的事,比如抽菸、喝酒、燙頭、玩手機。
客戶端 | 服務端 | |
同步阻塞(BIO) | 不能做事 | 不能做事 |
同步非阻塞(NIO) | 不能做事 | 能做其他事 |
異步阻塞 | 可以做其他事,等待異步回調 | 不能做其他事情 |
異步非阻塞(AIO) | 可以做其他事,等待異步回調 | 可以做其他事情 |
小結
分開來看,同步異步是相對於客戶端來說,而阻塞非阻塞是相對於服務端來說。因此,只需要看客戶端是同步或異步的。服務端是阻塞或非阻塞的。
異步 的優勢顯而易見,大大優化用戶體驗, 非阻塞 使得系統資源開銷遠遠小於 阻塞 模式,因爲系統不需要創建新的進程(或線程),大大地節省了系統多出來的系統資源可以給其他的中間件去服務了。
參考資料
https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/BIO-NIO-AIO.md