Java的IO演進
在JDK1.4推出Java NIO之前,基于Java的所有Socket通信都采用了同步阻塞模式(BIO),這種——請求——應答的通信模型簡化了上層的應用開發,但是在性能和可靠性方面卻存在著巨大的瓶頸。因此,在很長一段時間里,大型的應用服務器都采用C或者C++語言開發,因為它們可以直接使用操作系統提供的異步I/O(AIO)能力。當并發訪問量增大,響應時間延遲增大之后,采用Java BIO并發的服務端軟件只有通過硬件的不斷擴容來滿足高并發和低延時,它極大地增加了企業的成本,并且隨著集群規模的不斷膨脹,系統的可維護性也面巨大的挑戰,只能通過采購性能更高的硬件服務器來解決問題,這會導致惡性循環。
正是由于Java傳統BIO的拙劣表現,才使得Java支持非阻塞I/O的呼的呼聲日漸高漲,最終,JDK1.4版本提供了新的NIO類庫(new input/output),Java終于也可以支持非阻塞I/O了。從JDK1.0到JDK1.3,Java的I/O類庫都非常原始,很多UNIX網絡編程中的概念或者接口在I/O類庫中都沒有體現,例如:Pipe,Channel,Buffer和Selector等。2002年發布JDK1.4時,NIO以JSR-51的身份正式隨JDK發布。NIO主要的類和接口如下:
-
進行異步I/O操作的緩沖區ByteBuffer等;
-
進行異步I/O操作的管道Pipe;
-
進行各種I/O操作(異步或者同步)的Channel,包括ServerSocketChannel和SocketChannel;
-
多種字符集的編碼能力和解碼能力;
-
實現非阻塞I/O操作的多路復用器Selector;
-
基于流行的Perl實現的正則表達式類庫;
-
文件通道FileChannel;
新的NIO類庫的提供,極大地促進了基于Java的異步非阻塞編程的發展和應用,但是,它依然有不完善的地方,特別是對文件系統的處理能力仍顯不足,主要問題如下:
-
沒有統一的文件屬性(例如讀寫權限)
-
API能力比較弱,例如目錄的級聯創建和遞歸遍歷,往往需要自己實現。
-
底層存儲系統的一些高級API無法使用。
-
所有的文件操作都是同步阻塞調用,不支持異步文件讀寫操作。
2011年7月28日,JDK1.7正式發布。它的一個比較大的亮點就是將原來的NIO類庫進行了升級,被稱為NIO2.0。NIO2.0由JSR-203演進而來,它主要提供了如下三個方面的改進。
-
提供能夠批量獲取文件屬性的API,這些API具有平臺無關性,不與特性的文件系統相耦合,另外它還提供了標準文件系統的SPI,供各個服務提供商擴展實現
-
提供AIO功能,支持基于文件的異步I/O操作和針對網絡套接字的異步操作
-
完成JSR-51定義的通道功能,包括對配置和多播數據報的支持等。