摘要:為了講清復用的是什么,首先得先說明一下邏輯流的概念。理解了這個,那么所謂的復用,指的就是在一個邏輯流里處理多個事件如何做到利用多路復用器,輪詢監聽各路,如果一旦有事件發生,那么就去處理,否則程序阻塞。
java nio提供了一套稱為I/O多路復用的編程范式,那么什么叫做I/O多路復用呢?
所謂的I/O多路復用,從字面意思上來理解,就是:
有多個I/O操作(或是寫,或是讀,或是請求),這多個I/O操作都共用一個邏輯流。
為了講清復用的是什么,首先得先說明一下邏輯流的概念。
邏輯流是什么?這里的邏輯流和操作系統中"線程是進程的一個邏輯流"是一個意思。
下面的就是一個邏輯流:
{ int a = 5; int b a*a; double c = a/b; }
下面又是一個邏輯流:
{ long b = 5; int c = b+3; }
如果在一個進程中,如果沒有線程,那么程序是順序執行的,那么所有的代碼都是屬于一個邏輯流。
比如說,上面的兩端代碼,如果合在一個進程當中,它們一定是這種結構:
{ int a = 5; int b a*a; double c = a/b; } .... { long b = 5; int c = b+3; }
或是
{ long b = 5; int c = b+3; } .... { int a = 5; int b a*a; double c = a/b; }
也就是說它們一定屬于一個邏輯流(一個順序結構)。
理解了這個,那么所謂的I/O復用,指的就是在一個邏輯流里處理多個I/O事件?。?!
如何做到?利用Selector多路復用器,輪詢監聽各路I/O,如果一旦有I/O事件發生,那么就去處理,否則程序阻塞。
來看一個程序,加深理解:
package qiuqi.filedownloadtest; import java.io.FileInputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.*; import java.util.Iterator; public class FileServer { public static void main(String[] args) throws IOException { startServer(); } public static void startServer() throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.bind(new InetSocketAddress(9999)); serverSocketChannel.configureBlocking(false); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (selector.select() > 0) { Iteratoriterator = selector.selectedKeys().iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); iterator.remove(); if(key.isAcceptable()) { System.out.println("收到連接這個I/O事件"); catch (IOException e){e.printStackTrace();} } } } } }
這是一個監聽網絡I/O的多路復用程序,java中只能監聽網絡I/O,不能監聽標準輸入輸出等I/O(不過這些在linux里都可以)。
我們發現,這個程序的原理就是開啟一個網絡I/O類,ServerSocketChannel,把它注冊到Selector(選擇器)上,然后選擇器就開始
輪詢,直到發現一個I/O事件,于是就進入第一個while循環進行處理,否則一直阻塞在select()>0處。
這是一個極其簡陋的程序,但是它揭示了多路復用的真正內涵,也就是用一個邏輯流監聽,處理多個I/O(不過處理程序其實可以開啟多線程,也就是指第一個while循環里的部分)。
這就是I/O多路復用?。。?/p>
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/73557.html
摘要:為解決這問題,我們發現元兇處在一線程一請求上,如果一個線程能同時處理多個請求,那么在高并發下性能上會大大改善。這樣一個線程可以同時發起多個調用,并且不需要同步等待數據就緒。表示當前就緒的事件類型。 JAVA NIO 一步步構建I/O多路復用的請求模型 摘要:本文屬于原創,歡迎轉載,轉載請保留出處:https://github.com/jasonGeng88/blog 文章一:JAVA ...
摘要:事件多路復用器收集資源的事件并且把這些事件放入隊列中,直到事件被處理時都是阻塞狀態。最后,處理事件多路復用器返回的每個事件,此時,與系統資源相關聯的事件將被讀并且在整個操作中都是非阻塞的。 本系列文章為《Node.js Design Patterns Second Edition》的原文翻譯和讀書筆記,在GitHub連載更新,同步翻譯版鏈接。 歡迎關注我的專欄,之后的博文將在專欄同步:...
閱讀 2654·2023-04-26 00:07
閱讀 2437·2021-11-15 11:37
閱讀 649·2021-10-19 11:44
閱讀 2175·2021-09-22 15:56
閱讀 1730·2021-09-10 10:50
閱讀 1507·2021-08-18 10:21
閱讀 2573·2019-08-30 15:53
閱讀 1637·2019-08-30 11:11