BIO

来自姬鸿昌的知识库
跳到导航 跳到搜索

BIO 是最传统的同步阻塞 IO 模型,服务端的实现是一个连接只有一个线程处理,线程在发起请求后,会等待连接返回。


此处的“同步阻塞”是在 IO 语境下的概念:

同步:发起一个 IO 操作时,在没有得到结果之前,该操作不返回结果,只有调用结束后,才能获取返回值并继续执行后续的操作。

阻塞:发起者在发起 IO 操作后,不能再处理其他业务,只能等待 IO 操作结束。

见:同步与异步、阻塞与非阻塞

常见的同步阻塞 IO 访问代码如下:

package io.github.jihch.bio;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class BIOTest {

    public static void main(String[] args) {

        ServerSocket server = null;

        try {
            server = new ServerSocket(8088);
            while (true) {

                Socket socket = server.accept();

                //创建一个线程处理 server.accept 产生的 socket 链路
                new Thread(new SocketHandler(server.accept())).start();
            }

        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            if (server != null) {
                try {
                    server.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

}


对于每个线程而言,它们内部的实现都使用了阻塞的调用方式,核心代码如下所示:

package io.github.jihch.bio;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class SocketHandler implements Runnable {

    private Socket socket;

    public SocketHandler(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InputStream is = socket.getInputStream();
            byte[] b = new byte[1024];
            while (true) {
                //使用 read 阻塞读
                int data = is.read(b);
                if (data != -1) {
                    //处理读取到的数据
                    System.out.println(b);
                } else {
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}