Java中 BIO、NIO、AIO 有什么区别及其代码示例?
时间: 2024-01-27 14:06:24 浏览: 94
好的,理解您的要求。关于您的问题:
Java中的BIO,NIO和AIO是网络编程中常用的三种不同I/O模型。BIO是同步阻塞I/O模型,NIO是同步非阻塞I/O模型,而AIO则是异步非阻塞I/O模型。
- BIO模型:阻塞I/O模式是一种传统的I/O操作模式,通过传统的流式操作进行读写。在BIO模型中,操作系统内核会等待应用程序提供要读取或写入的数据,直到数据准备好后再进行读写操作。这种I/O操作方式的缺点是效率低下,因为在等待I/O数据的过程中线程被阻塞,无法进行其他有用的任务,从而导致资源的浪费。
以下是一个使用BIO的代码示例:
```java
ServerSocket serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept(); // 阻塞等待客户端连接
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) { // 阻塞等待读取数据
outputStream.write(buffer, 0, len); // 阻塞等待写入数据
}
outputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
```
- NIO模型:非阻塞I/O模式也是一种流式I/O操作模式。在NIO模型中,不会让线程等待数据准备好再进行读写,而是通过Selector轮询来判断是否有数据准备好,从而避免了线程的阻塞等待。这种I/O操作方式的优点是效率高,因为线程不会被阻塞等待数据准备好,能够进行其他有用的任务。
以下是一个使用NIO的代码示例:
```java
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false); // 设置为非阻塞模式
serverSocketChannel.socket().bind(new InetSocketAddress(port));
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
int readyChannels = selector.select(); // 阻塞等待数据准备好
if (readyChannels == 0) {
continue;
}
Set<SelectionKey> selectedKeys = selector.selectedKeys(); // 获取准备好的所有通道的SelectionKey
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if (key.isAcceptable()) {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false); // 设置为非阻塞模式
socketChannel.register(selector, SelectionKey.OP_READ); // 注册读事件
} else if (key.isReadable()) {
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int len = socketChannel.read(buffer);
if (len > 0) {
buffer.flip();
socketChannel.write(buffer);
}
}
keyIterator.remove(); // 处理完后移除该SelectionKey
}
}
```
- AIO模型:异步非阻塞I/O模式是一种更高级的I/O操作模式,在Java中也称为NIO.2。在AIO模型中,不会让线程等待数据准备好再进行读写,而是在数据准备好后系统会通知应用程序进行读写操作。这种I/O操作方式的优点是效率和可扩展性都非常高,能够处理大量的并发操作。
以下是一个使用AIO的代码示例:
```java
public class AioServer {
public static void main(String[] args) throws Exception {
AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(port));
serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
@Override
public void completed(AsynchronousSocketChannel socketChannel, Void attachment) {
// 接收到客户端连接
serverSocketChannel.accept(null, this);
ByteBuffer buffer = ByteBuffer.allocate(1024);
socketChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer buffer) {
if (result > 0) {
buffer.flip();
socketChannel.write(buffer);
}
}
@Override
public void failed(Throwable exc, ByteBuffer buffer) {
// 读取数据失败
}
});
}
@Override
public void failed(Throwable exc, Void attachment) {
// 接受客户端连接失败
}
});
while (true) {
Thread.sleep(1000); // 主线程等待,否则AIO事件可能得不到执行
}
}
}
```
以上是三种I/O模型的区别及其对应的代码示例。希望对您有所帮助。
阅读全文