1. 程式人生 > >談IO中的阻塞和非阻塞,同步和異步及三種IO模型

談IO中的阻塞和非阻塞,同步和異步及三種IO模型

狀態 阻塞io 舉例 最大的 data- str 被調用 當我 返回

什麽是同步和異步?

燒水,我們都是通過熱水壺來燒水的。在很久之前,科技還沒有這麽發達的時候,如果我們要燒水,需要把水壺放到火爐上,我們通過觀察水壺內的水的沸騰程度來判斷水有沒有燒開。隨著科技的發展,現在市面上的水壺都有了提醒功能,當我們把水壺插電之後,水壺水燒開之後會通過聲音提醒我們水開了。對於燒水這件事兒來說,傳統水壺的燒水就是同步的,高科技水壺的燒水就是異步的。

同步請求,A調用B,B的處理是同步的,在處理完之前他不會通知A,只有處理完之後才會明確的通知A。

異步請求,A調用B,B的處理是異步的,B在接到請求後先告訴A我已經接到請求了,然後異步去處理,處理完之後通過回調等方式再通知A。

所以說,同步和異步最大的區別就是被調用方的執行方式和返回時機。同步指的是被調用方做完事情之後再返回,異步指的是被調用方先返回,然後再做事情,做完之後再想辦法通知調用方。

什麽是阻塞和非阻塞?

還是那個燒水的例子,當你把水放到水壺裏面,按下開關後,你可以坐在水壺前面,別的事情什麽都不做,一直等著水燒好。你還可以先去客廳看電視,等著水開就好了。對於你來說,坐在水壺前面等就是阻塞的,去客廳看電視等著水開就是非阻塞的。

阻塞請求,A調用B,A一直等著B的返回,別的事情什麽也不幹。

非阻塞請求,A調用B,A不用一直等著B的返回,先去忙別的事情了。

所以說,阻塞和非阻塞最大的區別就是在被調用方返回結果之前的這段時間內,調用方是否一直等待。阻塞指的是調用方一直等待別的事情什麽都不做。非阻塞指的是調用方先去忙別的事情。

那阻塞和同步,非阻塞和異步是一回事嗎?

肯定不是。

阻塞、非阻塞和同步、異步的區別

首先,前面已經提到過,阻塞、非阻塞和同步、異步其實針對的對象是不一樣的。阻塞、非阻塞說的是調用者,同步、異步說的是被調用者。有人認為阻塞和同步是一回事兒,非阻塞和異步是一回事。但是這是不對的。

先來看同步場景中是如何包含阻塞和非阻塞情況的。

我們是用傳統的水壺燒水。在水燒開之前我們一直做在水壺前面,等著水開。這就是阻塞的。

我們是用傳統的水壺燒水。在水燒開之前我們先去客廳看電視了,但是水壺不會主動通知我們,需要我們時不時的去廚房看一下水有沒有燒開。這就是非阻塞的。

再來看異步場景中是如何包含阻塞和非阻塞情況的。

我們是用帶有提醒功能的水壺燒水。在水燒發出提醒之前我們一直做在水壺前面,等著水開。這就是阻塞的。

我們是用帶有提醒功能的水壺燒水。在水燒發出提醒之前我們先去客廳看電視了,等水壺發出聲音提醒我們。這就是非阻塞的。

Java中的三種IO模型

在Java語言中,一共提供了三種IO模型,分別是阻塞IO(BIO)、非阻塞IO(NIO)、異步IO(AIO)。

這裏面的BIO和NIO都是同步的IO模型,即同步阻塞IO和同步非阻塞IO,異步IO指的是異步非阻塞IO。

BIO (Blocking I/O):同步阻塞I/O模式,數據的讀取寫入必須阻塞在一個線程內等待其完成。

NIO (New I/O):同時支持阻塞與非阻塞模式,但主要是使用同步非阻塞IO。

AIO (Asynchronous I/O):異步非阻塞I/O模型。

通俗的話講,用燒水舉例:

BIO (Blocking I/O):有一排水壺在燒開水,BIO的工作模式就是,叫一個線程停留在一個水壺那,直到這個水壺燒開,才去處理下一個水壺。但是實際上線程在等待水壺燒開的時間段什麽都沒有做。

NIO (New I/O):NIO的做法是叫一個線程不斷的輪詢每個水壺的狀態,看看是否有水壺的狀態發生了改變,從而進行下一步的操作。

AIO ( Asynchronous I/O):為每個水壺上面裝了一個開關,水燒開之後,水壺會自動通知我水燒開了。

談IO中的阻塞和非阻塞,同步和異步及三種IO模型