技术文摘
深入剖析 Java 网络编程中的 BIO、NIO 与 AIO 结合代码详解
2024-12-31 05:35:51 小编
在当今的软件开发领域,网络编程是至关重要的一部分。而在 Java 中,BIO(Blocking I/O)、NIO(Non-Blocking I/O)和 AIO(Asynchronous I/O)是常见的 I/O 模型。本文将深入剖析这三种模型,并结合代码进行详细解释。
BIO 是 Java 传统的 I/O 模型,其特点是在进行输入输出操作时会阻塞线程。以下是一个简单的 BIO 示例代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class BIOServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(8080)) {
System.out.println("服务器启动,监听端口 8080...");
while (true) {
Socket socket = serverSocket.accept();
System.out.println("接收到新连接");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
String line;
while ((line = reader.readLine())!= null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上述代码中,serverSocket.accept() 方法会阻塞线程,直到有新的连接到来。这种阻塞方式在并发量较大时,会导致性能瓶颈。
NIO 则是一种非阻塞的 I/O 模型,通过通道(Channel)和缓冲区(Buffer)来实现。以下是一个 NIO 示例代码:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class NIOServer {
public static void main(String[] args) {
try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) {
serverSocketChannel.bind(new InetSocketAddress(8080));
System.out.println("服务器启动,监听端口 8080...");
while (true) {
SocketChannel socketChannel = serverSocketChannel.accept();
if (socketChannel!= null) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = socketChannel.read(buffer);
if (bytesRead > 0) {
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
String message = new String(bytes);
System.out.println(message);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
AIO 是异步 I/O 模型,真正实现了异步操作。以下是一个简单的 AIO 示例代码:
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public class AIOServer {
public static void main(String[] args) {
try (AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open()) {
serverSocketChannel.bind(new java.net.InetSocketAddress(8080));
System.out.println("服务器启动,监听端口 8080...");
while (true) {
Future<AsynchronousSocketChannel> future = serverSocketChannel.accept();
AsynchronousSocketChannel socketChannel = future.get();
if (socketChannel!= null) {
socketChannel.read(ByteBuffer.allocate(1024), null, new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
ByteBuffer buffer = (ByteBuffer) attachment;
buffer.flip();
String message = StandardCharsets.UTF_8.decode(buffer).toString();
System.out.println(message);
}
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
});
}
}
} catch (IOException | InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
BIO 简单但效率较低,NIO 提高了并发处理能力,AIO 则更进一步实现了异步操作。在实际应用中,应根据具体的业务需求和性能要求选择合适的 I/O 模型。
- 用 HTML 和 CSS 实现文本与选择框宽度一致
- 用JavaScript打造进度条
- 用 Sails.js 进行数据处理
- JavaScript 中利用 Web Workers 和 SIMD.js 实现并行编程
- JavaScript中Navigator对象有何作用
- LINK元素媒体属性的作用
- HTML和CSS创建进度条的方法
- CSS选择属性值以指定值结尾的元素方法
- CSS隐藏网页插入符号的方法
- Nightmare.js:全面介绍与安装指南
- FabricJS 中怎样裁剪克隆图像的高度
- CSS创建流星动画效果的方法
- JavaScript 被认为是松散类型语言的原因
- CSS 中用于设置元素背景图像的属性是哪个
- JavaScript中把连字符转换为驼峰式大小写的方法