侧边栏壁纸
博主头像
ZHD的小窝博主等级

行动起来,活在当下

  • 累计撰写 79 篇文章
  • 累计创建 53 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

理解BIO

江南的风
2016-05-07 / 0 评论 / 0 点赞 / 24 阅读 / 4246 字 / 正在检测是否收录...

BIO,全称是Blocking I/O(阻塞I/O),是Java中的一种传统IO操作模式,其相关的类和接口位于java.io包中。BIO是一种同步并阻塞的IO模型,意味着当一个线程执行IO操作时,如果该操作未完成(例如,没有数据可读或没有写入数据的空间),该线程将一直等待,直到操作完成。

基于以上IO数据流转过程,BIO采用以下线程模型实现:

1. 工作机制

  1. 服务器端

    • 服务器端启动一个ServerSocket,绑定IP地址和端口,并启动监听。

    • 当有客户端连接请求时,服务器端需要为每个客户端连接启动一个新的线程(或从线程池中获取线程)来处理该连接。

    • 客户端与服务器之间的数据交换(读/写操作)都是阻塞的,即一个线程在处理一个客户端连接时,必须等待读/写操作完成才能继续执行其他操作。

  2. 客户端

    • 客户端通过Socket与服务器建立连接。

    • 连接建立后,客户端与服务器之间的数据交换也是阻塞的。

2. 优缺点

优点:

  • 代码简单直观:BIO模型的代码相对简单,易于理解和实现。

缺点:

  • 资源消耗大:在并发连接数较多的情况下,需要为每个连接创建新的线程(或复用线程池中的线程),这会导致大量的线程上下文切换和内存消耗,从而影响系统性能。

  • 扩展性差:随着并发连接数的增加,服务器端的性能将显著下降,因为线程资源是有限的。

  • 响应慢:在单个线程处理多个连接时,如果某个连接上的操作阻塞了线程,那么其他连接上的操作也将被阻塞,导致整体响应速度变慢。

3. BIO的例子

import java.io.*;  
import java.net.ServerSocket;  
import java.net.Socket;  
  
public class BIOServer {  
    public static void main(String[] args) throws IOException {  
        // 监听端口  
        int port = 12345;  
        try (ServerSocket serverSocket = new ServerSocket(port)) {  
            System.out.println("Server is running on port " + port);  
  
            while (true) {  
                // 等待客户端连接  
                Socket clientSocket = serverSocket.accept();  
                System.out.println("New client connected from " + clientSocket.getInetAddress().getHostAddress());  
  
                // 为每个客户端连接创建一个新的线程  
                new ClientHandler(clientSocket).start();  
            }  
        }  
    }  
  
    static class ClientHandler extends Thread {  
        private Socket socket;  
  
        public ClientHandler(Socket socket) {  
            this.socket = socket;  
        }  
  
        @Override  
        public void run() {  
            try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
                 PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {  
                String inputLine;  
                while ((inputLine = in.readLine()) != null) {  
                    System.out.println("Received from client: " + inputLine);  
                    out.println("Hello from server!");  
                    if ("exit".equalsIgnoreCase(inputLine)) {  
                        break;  
                    }  
                }  
            } catch (IOException e) {  
                e.printStackTrace();  
            } finally {  
                try {  
                    socket.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }  
}

0

评论区