# BIO
作者:Ethan.Yang
博客:https://blog.ethanyang.cn (opens new window)
IO(Input/Output,输入输出)是计算机程序与外部环境进行数据交换的方式。Java中的IO操作包括文件读写、网络通信等。 阻塞IO指的是在进行读写操作时,如果数据没有准备好,线程会被阻塞(等待),直到操作完成。
# 一、Java传统IO体系结构
Java提供了两套IO API:
- 字节流(InputStream / OutputStream)
- 字符流(Reader / Writer)
它们是阻塞IO的典型代表,常用来操作文件和网络。
# 二、阻塞IO的工作原理
阻塞IO的核心是同步阻塞模型。调用read()或write()方法时,线程会等待操作完成,才继续执行。
举例:InputStream.read()方法会阻塞调用线程,直到有数据可读或流结束。
# 三、阻塞IO示例代码
# 示例
import java.io.*;
public class BlockingIOFileExample {
public static void main(String[] args) {
// 写文件
try (FileOutputStream fos = new FileOutputStream("data.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
String content = "Hello, Blocking IO!";
bos.write(content.getBytes());
bos.flush();
} catch (IOException e) {
e.printStackTrace();
}
// 读文件
try (FileInputStream fis = new FileInputStream("data.txt");
BufferedInputStream bis = new BufferedInputStream(fis)) {
byte[] buffer = new byte[1024];
// 这里会阻塞直到读取到数据
int len = bis.read(buffer);
if (len > 0) {
String readContent = new String(buffer, 0, len);
System.out.println("Read from file: " + readContent);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 网络Socket阻塞IO示例(简单服务器)
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class BlockingIOServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(12345);
System.out.println("Server started on port 12345");
while (true) {
// 阻塞等待客户端连接
Socket client = server.accept();
System.out.println("Client connected: " + client.getRemoteSocketAddress());
try (BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()))) {
String line;
// 阻塞等待客户端数据
while ((line = in.readLine()) != null) {
System.out.println("Received: " + line);
out.write("Echo: " + line + "\n");
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
client.close();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 四、阻塞IO的优缺点
# 优点
- API简单,易于使用,代码逻辑清晰
- 适合小并发、简单的文件或网络操作
# 缺点
- 线程资源消耗大,阻塞等待导致性能瓶颈
- 不适合高并发、大规模网络应用
- 线程阻塞可能造成响应迟缓
# 五、调优与实践技巧
- 使用缓冲流:
BufferedInputStream、BufferedOutputStream等减少系统调用次数,提高效率 - 多线程:通过线程池处理客户端连接,提升并发能力,但仍受线程资源限制
- 避免阻塞过久:合理设置超时,避免单个线程长期阻塞
NIO →