都是NIO是面向缓冲区的非阻塞的io,面向缓冲区倒是好理解,非阻塞到底体现在什么地方?莫不是selector使得NIO是非阻塞的?像下面代码:
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);
while (bytesRead != -1) {
System.out.println("Read " + bytesRead);
buf.flip();
while(buf.hasRemaining()){
System.out.print((char) buf.get());
}
buf.clear();
bytesRead = inChannel.read(buf);
}
aFile.close();
在int bytesRead = inChannel.read(buf);
的时候岂不是也是阻塞的?
服務端的selector上註冊了讀取事件,某時刻客戶端給服務端發送了一些數據,阻塞I/O這時會調用read()方法阻塞地讀取數據,而NIO的服務端會在selector中添加一個讀事件。服務端的處理執行緒會輪詢地存取selector,如果存取selector時發現有感興趣的事件到達,則處理這些事件,如果沒有感興趣的事件到達,則處理執行緒會一直阻塞直到感興趣的事件到達為止。
具體可以看這裡:
Java阻塞IO與非阻塞IO
首先你要知道阻塞和非阻塞的概念,阻塞體現在這個線程不能做別的了,只能在這裡等著。非阻塞體現在這個線程可以去幹別的,不需要一直在這等著。
說NIO的非阻塞原理之前,我們需要先說一下傳統的io。傳統的IO是按位元組傳輸的,即每次傳輸一個位元組。為了提高資料傳輸效率,引進了帶緩衝區得輸入輸出模式,這樣每次就可以傳輸大量的位元組數,但是,會導致在讀(寫)緩衝區沒有滿的情況下,程式會一直等待,直到滿或關閉流才能讀取(寫入)。這樣導致程式阻塞,降低了程式的執行效率。 、