本文目录导读:

我来通过几个典型的案例来说明Java IO等待的情况:
传统阻塞IO(BIO)等待案例
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class BioServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("服务器启动,等待客户端连接...");
while (true) {
// 这里会阻塞,等待客户端连接
Socket socket = serverSocket.accept();
System.out.println("客户端连接:" + socket.getRemoteSocketAddress());
// 为每个客户端创建一个线程处理
new Thread(() -> {
try {
handleClient(socket);
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
private static void handleClient(Socket socket) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
String line;
while ((line = in.readLine()) != null) {
System.out.println("收到消息:" + line);
out.println("服务器响应:" + line.toUpperCase());
}
}
}
阻塞文件读取
import java.io.*;
import java.nio.charset.StandardCharsets;
public class BlockingFileRead {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
try (InputStream is = new FileInputStream("large_file.txt")) {
byte[] buffer = new byte[1024];
int bytesRead;
System.out.println("开始读取文件...");
while ((bytesRead = is.read(buffer)) != -1) {
// 模拟处理数据
new String(buffer, 0, bytesRead, StandardCharsets.UTF_8);
// 每个循环打印进度
System.out.println("读取了 " + bytesRead + " 字节");
}
} catch (IOException e) {
e.printStackTrace();
}
long duration = System.currentTimeMillis() - startTime;
System.out.println("文件读取完成,耗时:" + duration + "ms");
}
}
等待日志文件写入(模拟等待场景)
import java.io.*;
import java.util.Random;
import java.util.concurrent.*;
public class IOWaitingDemo {
private static final BlockingQueue<String> logQueue = new LinkedBlockingQueue<>();
public static void main(String[] args) throws Exception {
// 创建多个任务同时写入日志
ExecutorService executor = Executors.newFixedThreadPool(3);
System.out.println("开始并发写入日志...");
long startTime = System.currentTimeMillis();
// 创建3个写日志任务
for (int i = 0; i < 3; i++) {
final int taskId = i;
executor.submit(() -> {
try {
writeLog("日志任务-" + taskId);
} catch (InterruptedException | IOException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
});
}
executor.shutdown();
executor.awaitTermination(30, TimeUnit.SECONDS);
long duration = System.currentTimeMillis() - startTime;
System.out.println("所有日志写入完成,总耗时:" + duration + "ms");
}
private static void writeLog(String taskName) throws InterruptedException, IOException {
File logFile = new File("logs_" + taskName + ".log");
try (BufferedWriter writer = new BufferedWriter(new FileWriter(logFile))) {
Random random = new Random();
for (int i = 0; i < 10; i++) {
// 模拟IO等待:随机延迟
Thread.sleep(random.nextInt(500));
writer.write("[" + taskName + "] 日志第" + (i+1) + "行: " + System.currentTimeMillis());
writer.newLine();
System.out.println(taskName + " 写入第 " + (i+1) + " 行日志");
}
}
}
}
NIO非阻塞与等待对比
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Set;
public class NIOVsBIODemo {
public static void main(String[] args) throws IOException {
// NIO 非阻塞服务器
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false); // 非阻塞模式
serverChannel.bind(new InetSocketAddress(9090));
Selector selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("NIO服务器启动,等待连接...");
while (true) {
// 非阻塞地等待事件
int readyChannels = selector.select(100); // 最多等待100ms
if (readyChannels == 0) {
System.out.println("当前无连接请求,可以执行其他任务...");
continue;
}
Set<SelectionKey> keys = selector.selectedKeys();
for (SelectionKey key : keys) {
if (key.isAcceptable()) {
// 接受连接
SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept();
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ);
System.out.println("接受新连接:" + clientChannel.getRemoteAddress());
} else if (key.isReadable()) {
// 读取数据
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = clientChannel.read(buffer);
if (bytesRead == -1) {
clientChannel.close();
key.cancel();
} else if (bytesRead > 0) {
String message = new String(buffer.array(), 0, bytesRead);
System.out.println("收到消息:" + message);
// 响应客户端
ByteBuffer response = ByteBuffer.wrap(("已收到: " + message).getBytes());
clientChannel.write(response);
}
}
}
keys.clear();
}
}
}
模拟数据库查询等待
import java.util.concurrent.*;
import java.util.*;
public class DatabaseWaitingSimulation {
private static final Map<String, Connection> connections = new ConcurrentHashMap<>();
static class Connection {
private boolean inUse = false;
private int id;
Connection(int id) {
this.id = id;
}
synchronized boolean acquire() {
if (!inUse) {
inUse = true;
return true;
}
return false;
}
synchronized void release() {
inUse = false;
}
@Override
public String toString() {
return "Connection-" + id;
}
}
public static void main(String[] args) throws Exception {
// 初始化连接池
for (int i = 1; i <= 3; i++) {
connections.put("conn-" + i, new Connection(i));
}
ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<String>> results = new ArrayList<>();
System.out.println("模拟数据库并发查询...");
// 创建10个并发查询任务
for (int i = 0; i < 10; i++) {
final int queryId = i;
Future<String> future = executor.submit(() -> {
return executeQuery(queryId);
});
results.add(future);
}
// 收集结果
for (Future<String> future : results) {
System.out.println(future.get());
}
executor.shutdown();
}
private static String executeQuery(int queryId) throws InterruptedException {
System.out.println("查询 " + queryId + " 开始,等待连接池分配连接...");
// 等待空闲连接
Connection connection = null;
long startWait = System.currentTimeMillis();
while (connection == null) {
// 尝试获取连接
for (Connection conn : connections.values()) {
if (conn.acquire()) {
connection = conn;
break;
}
}
if (connection == null) {
// 没有空闲连接,等待100ms后重试
Thread.sleep(100);
// 等待超时检查
if (System.currentTimeMillis() - startWait > 2000) {
return "查询 " + queryId + " 等待超时";
}
}
}
try {
// 模拟查询操作
Thread.sleep(new Random().nextInt(300) + 100);
String result = "查询 " + queryId + " 完成,使用连接: " + connection;
return result;
} finally {
// 释放连接
connection.release();
}
}
}
异步IO(AIOC)非阻塞演示
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.Future;
public class AsyncFileRead {
public static void main(String[] args) throws Exception {
Path path = Paths.get("async_data.txt");
// 创建文件
try (FileWriter writer = new FileWriter(path.toFile())) {
for (int i = 0; i < 1000; i++) {
writer.write(i + "\n");
}
}
// 异步读取
AsynchronousFileChannel channel = AsynchronousFileChannel.open(
path,
StandardOpenOption.READ
);
ByteBuffer buffer = ByteBuffer.allocate(1024);
System.out.println("开始异步读取文件...");
// 发起异步读取操作
Future<Integer> result = channel.read(buffer, 0);
// 异步读取期间可以执行其他任务
System.out.println("文件正在读取中,执行其他任务...");
Thread.sleep(1000);
System.out.println("其他任务执行完成");
// 等待读取完成
int bytesRead = result.get();
System.out.println("文件读取完成,共读取:" + bytesRead + " 字节");
buffer.flip();
String content = StandardCharsets.UTF_8.decode(buffer).toString();
System.out.println("文件内容(前100字符):" + content.substring(0, Math.min(100, content.length())));
channel.close();
}
}
关键要点
- BIO(阻塞IO):每个IO操作会阻塞当前线程直到完成
- NIO(非阻塞IO):使用Selector实现多路复用,避免线程阻塞
- AIO(异步IO):通过Future或Callback实现真正的异步操作
- 连接池:解决数据库连接等资源的等待问题
- 线程池:避免频繁创建销毁线程造成的IO等待
这些案例展示了IO等待对性能的影响以及如何使用不同技术来优化,在实际应用中,应根据场景选择合适的IO模型。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播