18.1.5 Java IO/NIO/AIO对比分析
1. IO模型基础概念
1.1 IO模型分类
- BIO (Blocking IO):同步阻塞IO,传统的Java IO
- NIO (Non-blocking IO):同步非阻塞IO,JDK 1.4引入
- AIO (Asynchronous IO):异步非阻塞IO,JDK 1.7引入
1.2 同步与异步、阻塞与非阻塞
// 同步阻塞:调用者等待结果返回
public String syncBlocking() {
return "数据读取完成"; // 线程会一直等待
}
// 同步非阻塞:调用者主动轮询结果
public String syncNonBlocking() {
while (true) {
String result = tryRead();
if (result != null) return result;
// 继续轮询
}
}
// 异步非阻塞:通过回调获取结果
public void asyncNonBlocking(Callback callback) {
CompletableFuture.supplyAsync(() -> "数据读取完成")
.thenAccept(callback::onComplete);
}
2. BIO (Blocking IO) 详解
2.1 BIO基本特点
- 同步阻塞模式
- 一个连接对应一个线程
- 线程在IO操作时会被阻塞
- 适合连接数较少的场景
2.2 BIO实现示例
public class BIOServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("BIO服务器启动,监听端口: 8080");
while (true) {
Socket clientSocket = serverSocket.accept(); // 阻塞等待
new Thread(() -> handleClient(clientSocket)).start();
}
}
private static void handleClient(Socket clientSocket) {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter writer = new PrintWriter(
clientSocket.getOutputStream(), true)) {
String inputLine;
while ((inputLine = reader.readLine()) != null) {
System.out.println("收到消息: " + inputLine);
writer.println("Echo: " + inputLine);
if ("bye".equalsIgnoreCase(inputLine)) break;
}
} catch (IOException e) {
System.err.println("处理客户端连接异常: " + e.getMessage());
}
}
}
3. NIO (Non-blocking IO) 详解
3.1 NIO核心组件
- Channel(通道):数据传输的管道
- Buffer(缓冲区):数据容器
- Selector(选择器):多路复用器
3.2 NIO实现示例
public class NIOServer {
public void start() throws IOException {
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("NIO服务器启动,监听端口8080");
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()) {
handleAccept(key, selector);
} else if (key.isReadable()) {
handleRead(key);
}
keyIterator.remove();
}
}
}
private void handleAccept(SelectionKey key, Selector selector) throws IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel clientChannel = serverChannel.accept();
if (clientChannel != null) {
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ,
ByteBuffer.allocate(1024));
}
}
private void handleRead(SelectionKey key) throws IOExcept
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
Java面试圣经 文章被收录于专栏
Java面试圣经,带你练透java圣经

查看7道真题和解析