Java NIO

IO v.s. NIO

功能

使用场景

NIO 原理

实现 NIO 的主要原理是轮询。即,一个线程,同时监听多个接口,如果这个接口有数据就读取,没有就检查下一个。

但是,轮询的缺点是浪费CPU资源,因为大部分时间可能都是无数据可读的。 所以,一种常用的改进方案是I/O多路复用(IOmultiplexing),即监听时,由事件驱动,当某个接口的数据好了,再过去读。

NIO 的三种模型

参考 -> https://blog.csdn.net/jiyiqinlovexx/article/details/51204726

NIO API

Core components

Multiple sources read/write from multiple channels into buffer(s), thus non-blocking.

Channel

Channel is similar to Stream, it is the gate for read/write.

Channels implementation

//create channel
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();

//create buffer with capacity of 48 bytes
ByteBuffer buf = ByteBuffer.allocate(48);

//read from channel into buffer
int bytesRead = inChannel.read(buf); 
while (bytesRead != -1) {
  buf.flip();  //filp the buffer mode from write to read
  while(buf.hasRemaining()){
    System.out.print((char) buf.get()); // read 1 byte at a time
  }
  buf.clear(); //filp the buffer mode from read to write
  bytesRead = inChannel.read(buf);
}
aFile.close();

Buffer

A buffer is essentially a block of memory into which you can write data, which you can then later read again.

Usage

Buffer implementation

Selector

Usage

Selector selector = Selector.open();
channel.configureBlocking(false);
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);
while(true) {
  int readyChannels = selector.select();
  if(readyChannels == 0) continue;
  Set<SelectionKey> selectedKeys = selector.selectedKeys();
  Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
  while(keyIterator.hasNext()) {
    SelectionKey key = keyIterator.next();
    if(key.isAcceptable()) {
        // a connection was accepted by a ServerSocketChannel.
    } else if (key.isConnectable()) {
        // a connection was established with a remote server.
    } else if (key.isReadable()) {
        // a channel is ready for reading
    } else if (key.isWritable()) {
        // a channel is ready for writing
    }
    keyIterator.remove();
  }
}
Fork me on GitHub