1. 程式人生 > >超雞容易理解的---同步異步,阻塞非阻塞

超雞容易理解的---同步異步,阻塞非阻塞

點菜 擔心 窗口 aio 幫我 狀態 主動 書店 一段

快來看超雞容易理解的同步異步,阻塞非阻塞,再也不擔心理解晦澀的語言了。

阻塞和非阻塞指的是執行一個操作是等操作結束再返回,還是馬上返回。

比如餐館的服務員為用戶點菜,當有用戶點完菜後,服務員將菜單給後臺廚師,此時有兩種方式:

  • 第一種:就在出菜窗口等待,直到廚師炒完菜後將菜送到窗口,然後服務員再將菜送到用戶手中;
  • 第二種:等一會再到窗口來問廚師,某個菜好了沒?如果沒有先處理其他事情,等會再去問一次;

第一種就是阻塞方式,第二種則是非阻塞的。

  同步和異步又是另外一個概念,它是事件本身的一個屬性。還拿前面點菜為例,服務員直接跟廚師打交道,菜出來沒出來,服務員直接指導,但只有當廚師將菜送到服務員手上,這個過程才算正常完成,這就是同步的事件。同樣是點菜,有些餐館有專門的傳菜人員,當廚師炒好菜後,傳菜員將菜送到傳菜窗口,並通知服務員,這就變成異步的了。其實異步還可以分為兩種:帶通知的和不帶通知的。前面說的那種屬於帶通知的。有些傳菜員幹活可能主動性不是很夠,不會主動通知你,你就需要時不時的去關註一下狀態。這種就是不帶通知的異步。

對於同步的事件,你只能以阻塞的方式去做。而對於異步的事件,阻塞和非阻塞都是可以的。非阻塞又有兩種方式:主動查詢和被動接收消息。被動不意味著一定不好,在這裏它恰恰是效率更高的,因為在主動查詢裏絕大部分的查詢是在做無用功。對於帶通知的異步事件,兩者皆可。而對於不帶通知的,則只能用主動查詢。

  但是對於非阻塞和異步的概念有點混淆,非阻塞只是意味著方法調用不阻塞,就是說作為服務員的你不用一直在窗口等,非阻塞的邏輯是"等可以讀(寫)了告訴你",但是完成讀(寫)工作的還是調用者(線程)服務員的你等菜到窗口了還是要你親自去拿。而異步意味這你可以不用親自去做讀(寫)這件事,你的工作讓別人(別的線程)來做,你只需要發起調用,別人把工作做完以後,或許再通知你,它的邏輯是

我做完了 告訴/不告訴 你,他和非阻塞的區別在於一個是"已經做完"另一個是"可以去做"

這也是NIOAIO最大的區別,就是NIO在有通知時可以進行相關操作,而AIO有通知時則代表操作已經完成

再舉一個例子:

  去書店借一本書,同步就是我要親自到書店,問老板有沒有這本書,阻塞就是老板查詢的時候(讀寫)我只能在那等著,老板找到書後把書交給我,這就是同步阻塞。

  我親自到書店借書,老板在找這本書的時候,我可以去幹別的,然後每隔一段時間去問老板書找到了沒有,也可以等老板找到書以後通知我,這就是同步非阻塞。

  我想借本書,找個人幫我去借,借到書以後再通知我,這就是異步,我只發起調用,但是本身並不參與這個事件,而是讓別的線程去做這個事。

  同步與異步是對應的,它們是線程之間的關系,兩個線程之間要麽是同步的,要麽是異步的。

  阻塞與非阻塞是對同一個線程來說的,在某個時刻,線程要麽處於阻塞,要麽處於非阻塞。

  幫我借書的那個人有沒有借到書,我可以打電話問他(輪詢),也可以等他通知我,這是異步的通知;在借書的過程中借書的那個人可以輪詢的方式查看書是否已經找到(緩沖區有沒有數據),找到了你可以把它拿走,也可以等老板找到書後通知我,這是非阻塞的通知與輪詢。

超雞容易理解的---同步異步,阻塞非阻塞