一、同步和異步
同步:一個事件或者任務的執行,會使整個流程暫時等待,也就是說如果有多個任務要執行,必須要逐個進行。
異步:一個事件或者任務的執行,不會使整個流程暫時等待,也就是說如果有多個任務要執行,可以並發去執行。
同步和異步的關鍵在於一個事件或者任務的執行是否會導致整個流程暫時等待。也就是任務是逐個完成的嗎
二、阻塞和非阻塞
阻塞:在某個事件或者任務執行的過程中,它發出了一個請求,但是由於該操作能夠執行所需要的條件還沒有達到,就會一直等待在那里,直到條件滿足。
非阻塞:在某個事件或者任務執行的過程中,它發出了一個請求,如果請求條件不滿足,會返回一個標志信息告知不滿足,不需要一直在那里等待。
阻塞和非阻塞的關鍵在於,當發出請求時,如果不滿足請求時是一直等待還是不需要等待。
三、阻塞IO和非阻塞IO
IO操作通常包括:對硬盤的讀寫、對socket的讀寫以及外圍設備的讀寫
一個完整的IO請求讀寫操作包括
(1)查看數據是否就緒;
(2)進行數據拷貝;
當線程發出一個IO請求操作的時候,內核會查看所需要讀寫的數據是否已經准備就緒,
阻塞IO:如果數據沒有准備就緒,就一直等待,直到數據准備就緒;
非阻塞IO:如果沒有准備就緒會返回一個標志信息,不需要等待,等到數據准備就緒以后,內核會把數據拷貝到線程中去。
阻塞IO和非阻塞IO關鍵在於數據沒有准備好時是否會等待;
四、同步IO和異步IO
同步IO:當一個線程請求進行IO操作時,當IO操作完成之前,該線程會被阻塞;
當線程發送IO請求操作時,數據沒有准備就緒,就會使用線程或者內核不停地去詢問數據有沒有准備好,當數據准備就緒后將數據從內核拷貝到線程。
異步IO:當一個線程請求進行IO操作時,當IO操作完成之前,該線程會不會被阻塞;
異步IO只有IO操作請求是線程發出的,查看數據是否准備和對數據的拷貝都是通過內核來完成的,發送通知告知線程IO操作已經完成,在異步IO中,不會對線程產生任何阻塞。
同步IO和異步IO都是的關鍵區別在於數據拷貝階段是由線程完成還是內核完成。所以異步IO必須要有底層操作系統的支持。
五、5種IO模型
同步IO
(1)阻塞IO
如果數據沒有准備就緒,就一直等待,直到數據准備就緒;就是傳統的IO模型。
(2)非阻塞IO
如果沒有准備就緒會返回一個標志信息,不需要等待,等到數據准備就緒以后,內核會把數據拷貝到線程中去。但是需要不斷詢問內核是否已經准備好數據,非阻塞雖然不用等待但是一直占用CPU。
(3)多路復用IO
Java NIO就是多路復用IO模型
多路復用IO,會有一個線程不斷地去輪詢多個socket的狀態,當socket有讀寫事件的時候才會調用IO 讀寫操作。
用一個線程管理多個socket,是通過selector.select()查詢每個通道是否有事件到達,如果沒有事件到達,則會一直阻塞在那里,因此也會帶來線程阻塞問題。
(4)信號驅動IO模型
在信號驅動IO模型中,當用戶發起一個IO請求操作時,會給對應的socket注冊一個信號函數,線程會繼續執行,當數據准備就緒的時候會給線程發送一個信號,線程接受到信號時,會在信號函數中進行IO操作。
非阻塞IO、多路復用IO、信號驅動IO都不會造成IO操作的第一步,查看數據是否准備就緒而帶來的線程阻塞,但是在第二步,對數據進行拷貝都會使線程阻塞。
異步IO
異步IO是最理想的IO模型,當線程發出一個IO請求操作時,接着就去做自己的事情了,內核去查看數據是否准備就緒和准備就緒后對數據的拷貝,拷貝完以后內核會給線程發送一個通知說整個IO操作已經完成了,數據可以直接使用了。
同步的IO操作在第二個階段,對數據的拷貝階段,都會造成線程的阻塞,異步IO則不會。
異步IO在IO操作的兩個階段,都不會使線程阻塞。
版權聲明:本文轉載自: https://blog.csdn.net/snow_7/article/details/51952796