在Java的世界里,IO指的是输入/输出,也就是我们常说的数据读写操作。NIO、AIO和BIO是Java中用于数据读写操作的三种不同的编程模式。
BIO (Blocking IO 同步阻塞IO)
BIO是最传统的IO模式。在这种模型中,每一个新的客户端连接都需要创建一个新的线程去处理,每个线程在处理IO操作时是阻塞的。这意味着如果一个线程正在等待网络数据到达,那在此期间它将不能执行任何其他任务。
BIO模式简单易懂,但缺点是不适合处理并发高、连接数多的应用,因为每个新连接都需要一个新线程,而线程是昂贵的操作系统资源,过多的线程会导致资源耗尽。
示例代码:
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
// 服务器线程阻塞等待连接
Socket clientSocket = serverSocket.accept();
// 为每个连接创建新的线程去处理
new Thread(new Runnable() {
public void run() {
// 读写数据...
}
}).start();
}
NIO (Non-blocking IO 非阻塞IO)
NIO是非阻塞IO模式,是Java 1.4版本引入的一个新的IO机制,也被称为New IO。NIO支持面向缓冲区的(Buffer-oriented)IO操作,并提供了选择器(Selector)机制,允许单个线程轮询多个IO通道(Channel),从而可以管理多个并发的客户端连接。
在NIO模式中,线程通常不会阻塞在真实的IO操作上,当没有数据可读或可写时,线程可以继续做其他事情。这种方式可以提升系统的并发能力及CPU的利用率。
示例代码:
Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(8080));
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
// 选择器监控所有注册的通道,当它们中有需要处理的IO操作时,该方法返回
if (selector.select() > 0) {
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> it = selectedKeys.iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
// 根据事件的不同进行处理...
it.remove();
}
}
}
AIO (Asynchronous IO 异步IO)
AIO也叫NIO 2,在Java 7中引入,提供了一个完全异步的IO操作方式。它是基于事件和回调机制的,可以直接对应于操作系统的异步IO。使用AIO时,你可以发起一个请求后立即做其他事情,当IO操作完成时,会得到通知,或者在读写操作完成时自动触发一个回调函数。
AIO适用于连接数目多但每个连接上的并发度并不高的应用场景,例如,异步地处理成千上万的连接,而每个连接每次只发送少量数据。
示例代码:
AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
@Override
public void completed(AsynchronousSocketChannel client, Void attachment) {
// 接收下一个连接
serverSocketChannel.accept(null, this);
// 处理当前的连接...
}
@Override
public void failed(Throwable exc, Void attachment) {
// 处理失败情况...
}
});
综上所述,BIO是阻塞且一个连接一个线程,NIO是非阻塞且使用Selector管理多个连接,AIO是异步可以自动回调的IO处理模型。