NIO與AIO,同步/異步,阻塞/非阻塞

1.flip(),compact(),與clear()的使用react

flip()內部實現,先將limit設爲當前位置,再將緩衝區的postion設爲0,因此是爲將緩衝區的數據寫出到其它通道或者get()做準備。服務器

clear()內部實現,將limit設爲緩衝區的容量,position設爲0,limit的不一樣爲clear()與flip()的區別,因此clear()是爲緩衝區的數據讀入與put()做準備。當將通道中的數據讀入緩衝區前,應該用clear(),不能用flip()app

compact()內部實現,首先將當前位置與limit之間的數據複製到緩衝區的開始處,假設複製了n字節的數據,而後將position設爲n+1,limit設爲容量,因此是爲了繼續往緩衝區讀入數據或者put()做準備,即爲追加數據做準備。框架

flip()與compact()配合使用的例子:異步

1 while(channel.read(buffer)>=0 || buffer.position!=0){
2     buffer.flip();    //爲寫出數據做準備,將position移至0
3     channel2.write(buffer);
4     buffer.compact();    //假如上一步只寫出了部分數據,此方法則能夠防止數據丟失,下次讀入的新數據將追加在後邊
5 }

SelectionKey關於accept,connect,read,write有幾個常量,這幾個值都是2的整數次冪,如1,4,8,16,所以進行 | 和 ^ 運算就如同十進制中的加法和減法,這樣能夠靈活的註冊和註銷關注的事件.async

如註銷監聽讀事件,key.interestOps(key.interestOps()^SelectionKey.OP_READ)  (1|4|8)^4=9  ^優先級比|高,所以括號不能少post

2.關於同步,異步,阻塞,非阻塞的區別spa

各類I/O模型的準確介紹:操作系統

http://blog.csdn.net/shallwake/article/details/5265287?reload.net

AIO介紹:還有一個相關服務器框架yanf4j :

http://www.iteye.com/topic/472333 

同步與異步的區分標準:數據從內核緩衝區(kernel buffer)複製到應用程序緩衝區(application buffer)這個階段是否阻塞。

因此從這個角度看,阻塞I/O,非阻塞I/O,多路複用I/O,signal driven I/O(僅限於Unix)這四種I/O模型都是同步I/O.

而asynchronous I/O操做系統在copy數據到應用緩衝區完成之後才通知應用程序,因此是純異步的。

在1.4的NIO中,阻塞的是select,I/O並不阻塞,用一個Reactor線程能夠監聽多個通道的事件,並分發給其它的處理線程。這個select能夠看做一個代理,它會去輪詢全部註冊的通道事件,看事件是否已發生,因此本質上NIO可當作是同步非阻塞I/O.

NIO應用的是Reactor模式,selector是reactor,而channel可看做是事件處理程序,如讀就緒事件發生時,若是通道設置的是非阻塞模式,則處理程序會將數據從內核緩衝區複製到通道中(應用緩衝區),緊接着咱們在程序中從通道中讀取數據時就不會阻塞了。

而NIO的同步體如今第一階段仍然須要經過輪詢來獲知讀/寫/是否已就緒,而後事件分離器調用相應事件處理程序。

AIO的Proactor模式,不關心讀就緒事件,只關心讀/寫完成事件,完成之後直接回調以前註冊的處理程序。I/O讀寫,緩衝區數據的移動所有由內核完成。

在1.7的AIO中,自己也不會阻塞,對accept,read,write的調用都會當即返回,內核完成I/O操做之後,會將後續處理任務提交給線程池來執行,即回調,這個Proactor就是當初注入的AsynchronousChannelGroup,它持有這個線程池。

相關文章
相關標籤/搜索