技术文摘
深入剖析 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 模型。
- 服务器成矿机,老板险些将我辞退
- 这波 React 确实遭到针对
- 深度剖析单例模式 绝非易事
- 灵魂之问:重复消费、顺序消费与分布式事务
- 面试官:谈对微信小程序的理解、优缺点
- JMX 的版本历史及代码示例
- Java 从零起步手写 RPC 之客户端调用服务端的实现方法
- 14 款常用测试开发工具推荐
- JavaScript 用户登录表单焦点事件浅析
- 苹果专利:以超声波检测定位 AR/VR 环境中的镜子存在
- SignalR 在 React 和 Go 技术栈中的实践
- IntelliJ IDEA 插件:两种开发方式创建插件工程
- 二分法仍需加强练习
- 从 MVC 到 ASP.NET Core 6.0 最小 API 的转变
- 每日算法:三角形有效性的个数