天天看點

JAVA NIO之簡介

     NIO(New IO)是從Java1.4開始引入的,是可以替代Java IO API 的API。與阻塞式IO(傳統IO)不同,他提出了非阻塞信道和事件驅動的IO程式設計模式。現在常見的技術架構,很多都采用了NIO技術,例如:Tomcat、Netty、Jetty等。是以,學習和掌握NIO技術已經是程式員們必備的技能。

     Java.nio包中包含了很多類群組件,提供了很多進階的特性。其中核心應屬:Channels、Buffer、Selector這三部分。Channel和Buffer有好幾種類型,channel的主要實作包括有:FileChannel、DatagramChannel、SocketChannel與ServerSocketChannel,涵蓋了TCP、UDP的網絡IO以及檔案IO。關于Buffer的實作基本是java基本類型的緩沖實作,即:ByteBuffer、CharBuffer、DoubleBuffer、IntBuffer、FloatBuffer、ShortBuffer、LongBuffer。其中,還有個MappedByteBuffer,用于表示記憶體映射檔案,大大提高了檔案的讀寫效率。Selector允許單線程處理多個Channel通道,如果你的應用打開了多個連接配接(通道),但每個連接配接的流量都很低,使用Selector就會很友善,例如在一個聊天伺服器中。下圖是一個單線程使用一個Selector處理三個channel的示圖:

JAVA NIO之簡介

要使用Selector,必須向Selector中注冊Channel,然後調用他的select()方法。這個方法會一直阻塞到某個注冊的通道有事件就緒,一旦這個方法傳回,線程就可以處理這些事件,事件的例子有如新連接配接進來,資料接收等。

       NIO與傳統IO之間第一個最大的差別是,IO是面向流的,NIO是面向緩沖區的。JAVA IO面向流意味着每次從流中讀一個或多個位元組,直至讀取所有位元組,它們沒有被緩存在任何地方。此外,它不能前後移動流中的資料。如果需要前後移動從流中讀區的資料,需要先将它緩存到一個緩沖區。NIO的緩沖導向方法略有不同。資料讀取到它稍後處理的緩沖區,需要時可在緩沖區中前後移動。這一特性增加了處理過程中的靈活性。但是,還需要檢查是否該緩沖區中包含所有您需要處理的資料。而且,需確定當更多的資料讀入緩沖區時,不要覆寫緩沖區裡尚未處理的資料。

       IO的各種流是阻塞的。這意味着,當一個線程調用read()或write()時,該線程被阻塞,直到有一些資料被讀取,或資料完全寫入。該線程在此期間不能再幹任何事情了。NIO的非阻塞模式,使一個線程從某通道發送請求讀取資料,但是它僅能得到目前可用的資料,如果目前沒有資料可用時,就什麼都不會擷取。而不是保持線程阻塞,是以直至資料變的可以讀取之前,該線程可以做其他的事情。非阻塞寫也是如此。一個線程請求寫入一些資料到某通道,但不需要等待他完全寫入,這個線程可以同時去做别的事情。線程通常将非阻塞IO的空閑時間用于在其他通道上執行IO操作,是以一個單獨的線程現在可以管理多個輸入和輸出的通道。

       總之,NIO的讀寫都是操作緩沖區(Buffer)的,然後通過通道(channel )進行資料的互動。這篇文章先大概總結下NIO的特性及基本概念,後面詳細貼出其具體的實作機制與執行個體。NIO中除了這三個核心部分外,還有Pipe、FileLock、Scatter(分散)/Gatter(聚集)、transferFrom/transferTo等,後面博文再一一詳細介紹。

下一篇: 1 NIO簡介

繼續閱讀