以 Java 为例简单说明常见 IO 模型

BIO 我们先看一个 Java 例子: package cn.bridgeli.demo; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; /** * @author bridgeli */ public class SocketBIO { public static void main(String[] args) throws Exception { ServerSocket server = new ServerSocket(9090, 20); System.out.println("step1: new ServerSocket(9090) "); while (true) { Socket client = server.accept(); System.out.println("step2:client: " + client.getPort()); new Thread(new Runnable() { @Override public void run() { InputStream inputStream = null; BufferedReader reader = null; try { inputStream = client.getInputStream(); reader = new BufferedReader(new InputStreamReader(inputStream)); while (true) { String dataLine = reader.readLine(); //阻塞2 if (null != dataLine) { System.out.println(dataLine); } else { client.close(); break; } } System.out.println("客户端断开"); } catch (IOException e) { e.printStackTrace(); } finally { if (null != reader) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (null!= inputStream) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }).start(); } } } BIO 是最初始的 IO 模型,该模型有两个大问题:1. accept 是阻塞的;2. read 也是阻塞的,也就是说我们的服务器起来之后,首先会在 accept 处阻塞,等待客户端连接,但有一个客户端连接的时候,我们可以从客户端处读取数据,这个时候也是阻塞的,所以我们的系统只能是单连接的,当有多个客户端连接的时候,只能一个一个的排着队连接,然后从客户端中读取数据,为了实现多连接,这就要求我们必须启用线程来解决,最开始等待客户端连接,然后有一个客户端连上了之后,启动一个线程读取客户端的数据,然后主线程继续等待客户端连接。 ...

March 30, 2021 · 3 min · 586 words · Bridge Li