# 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

# 网络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

# 四、阻塞IO的优缺点

# 优点

  • API简单,易于使用,代码逻辑清晰
  • 适合小并发、简单的文件或网络操作

# 缺点

  • 线程资源消耗大,阻塞等待导致性能瓶颈
  • 不适合高并发、大规模网络应用
  • 线程阻塞可能造成响应迟缓

# 五、调优与实践技巧

  • 使用缓冲流BufferedInputStreamBufferedOutputStream等减少系统调用次数,提高效率
  • 多线程:通过线程池处理客户端连接,提升并发能力,但仍受线程资源限制
  • 避免阻塞过久:合理设置超时,避免单个线程长期阻塞