天天看點

java基礎 NIO與IO的差別

java基礎 NIO與IO的差別

一、概述

NIO即New IO,這個庫是在JDK1.4中才引入的。NIO和IO有相同的作用和目的,但實作方式不同,NIO主要用到的是塊,是以NIO的效率要比IO高很多。在Java API中提供了兩套NIO,一套是針對标準輸入輸出NIO,另一套就是網絡程式設計NIO。

NIO和IO的主要差別,下表總結了Java IO和NIO之間的主要差別:

類型 IO NIO
流類型 面向流 面向緩沖
是否阻塞 阻塞IO 非阻塞IO
有無選擇器 選擇器
真正的了解NIO一定要看Netty,Netty是NIO裡用的最好的架構。
           

二、IO與NIO差別詳解

1、面向流與面向緩沖

  Java IO和NIO之間第一個最大的差別是,IO是面向流的,NIO是面向緩沖區的。 Java IO面向流意味着每次從流中讀一個或多個位元組,直至讀取所有位元組,因為它們沒有被緩存在任何地方,是以,它不能前後移動流中的資料。如果需要前後移動從流中讀取的資料,需要先将它緩存到一個緩沖區。

Java NIO的緩沖導向方法略有不同。資料讀取到一個它稍後處理的緩沖區,需要時可在緩沖區中前後移動。這就增加了處理過程中的靈活性。但是,還需要檢查是否該緩沖區中包含所有您需要處理的資料。而且,需確定當更多的資料讀入緩沖區時,不要覆寫緩沖區裡尚未處理的資料。

2、阻塞與非阻塞IO

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

3、選擇器(Selectors)

  Java NIO的選擇器允許一個單獨的線程來監視多個輸入通道,你可以注冊多個通道使用一個選擇器,然後使用一個單獨的線程來“選擇”通道:這些通道裡已經有可以處理的輸入,或者選擇已準備寫入的通道。這種選擇機制,使得一個單獨的線程很容易來管理多個通道。

4、NIO和IO适用場景

  NIO是為彌補傳統IO的不足而誕生的,但是尺有所短寸有所長,NIO也有缺點,因為NIO是面向緩沖區的操作,每一次的資料處理都是對緩沖區進行的,那麼就會有一個問題,在資料處理之前必須要判斷緩沖區的資料是否完整或者已經讀取完畢,如果沒有,假設資料隻讀取了一部分,那麼對不完整的資料處理沒有任何意義。是以每次資料處理之前都要檢測緩沖區資料。

  

  那麼NIO和IO各适用的場景是什麼呢?

  如果需要管理同時打開的成千上萬個連接配接,這些連接配接每次隻是發送少量的資料,例如聊天伺服器,這時候用NIO處理資料可能是個很好的選擇。

  而如果隻有少量的連接配接,而這些連接配接每次要發送大量的資料,這時候傳統的IO更合适。使用哪種處理資料,需要在資料的響應等待時間和檢查緩沖區資料的時間上作比較來權衡選擇。

三、Java NIO 總覽

Java NIO的三個核心基礎元件,Channels、Buffers、Selectors。其餘的諸如Pipe,FileLcok都是在使用以上三個核心元件時幫助更好使用的工具類。