<meta charset="utf-8">
NIO
NIO主要有三大核心部分:
Channel(通道),Buffer(緩沖區(qū)), Selector(選擇器,多路復(fù)用器)。
傳統(tǒng)IO基于字節(jié)流和字符流進(jìn)行操作,而NIO基于Channel和Buffer(緩沖區(qū))進(jìn)行操作,數(shù)據(jù)總是從通道讀取到緩沖區(qū)中,或者從緩沖區(qū)寫入到通道中。Selector(選擇區(qū))用于監(jiān)聽多個(gè)通道的事件(比如:連接打開,數(shù)據(jù)到達(dá))。因此,單個(gè)線程可以監(jiān)聽多個(gè)數(shù)據(jù)通道。
同步io和異步IO的區(qū)別
同步IO和異步IO模型是針對(duì)用戶線程和內(nèi)核的交互來說的:
對(duì)于同步IO:當(dāng)用戶發(fā)出IO請(qǐng)求操作之后,如果數(shù)據(jù)沒有就緒,需要通過用戶線程或者內(nèi)核不斷地去輪詢數(shù)據(jù)是否就緒,當(dāng)數(shù)據(jù)就緒時(shí),再將數(shù)據(jù)從內(nèi)核拷貝到用戶線程;
而異步IO:只有IO請(qǐng)求操作的發(fā)出是由用戶線程來進(jìn)行的,IO操作的兩個(gè)階段都是由內(nèi)核自動(dòng)完成,然后發(fā)送通知告知用戶線程IO操作已經(jīng)完成。也就是說在異步IO中,不會(huì)對(duì)用戶線程產(chǎn)生任何阻塞。
Channel
首先說一下Channel,國(guó)內(nèi)大多翻譯成“通道”。Channel和IO中的Stream(流)是差不多一個(gè)等級(jí)的。只不過Stream是單向的,譬如:InputStream, OutputStream.而Channel是雙向的,既可以用來進(jìn)行讀操作,又可以用來進(jìn)行寫操作。
NIO中的Channel的主要實(shí)現(xiàn)有:
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
這里看名字就可以猜出個(gè)所以然來:分別可以對(duì)應(yīng)文件IO、UDP和TCP(Server和Client)。下面演示的案例基本上就是圍繞這4個(gè)類型的Channel進(jìn)行陳述的。
Buffer
NIO中的關(guān)鍵Buffer實(shí)現(xiàn)有:ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer,分別對(duì)應(yīng)基本數(shù)據(jù)類型: byte, char, double, float, int, long, short。當(dāng)然NIO中還有MappedByteBuffer, HeapByteBuffer, DirectByteBuffer等這里先不進(jìn)行陳述。
Selector
Selector運(yùn)行單線程處理多個(gè)Channel,如果你的應(yīng)用打開了多個(gè)通道,但每個(gè)連接的流量都很低,使用Selector就會(huì)很方便。例如在一個(gè)聊天服務(wù)器中。要使用Selector, 得向Selector注冊(cè)Channel,然后調(diào)用它的select()方法。這個(gè)方法會(huì)一直阻塞到某個(gè)注冊(cè)的通道有事件就緒。一旦這個(gè)方法返回,線程就可以處理這些事件,事件的例子有如新的連接進(jìn)來、數(shù)據(jù)接收等。