BIO原理及代码实现

1、简单概念介绍

1. 同步与异步

同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式。java

  • 同步:同步调用请求发送后,调用者将一直等待被调用者返回消息,若无响应则一直等待没法进行后续操做,直至有消息返回。
  • 异步:异步调用请求发送后,调用者无需等待消息返回即可进行其余操做,消息会以通知的方式告知调用者。

2.阻塞与非阻塞

  • 阻塞:调用结果返回以前,当前线程会被挂起。调用线程只有在获得结果以后才会返回。
  • 非阻塞:不能马上获得结果以前,该调用不会阻塞当前线程。

2、BIO

  BIO(blocking/io)即同步阻塞IO,客户端链接时服务器需开启一个线程进行处理,让咱们来看下BIO的几种实现方式。服务器

1. 单线程实现

服务端实现:多线程

public class Server {
    public static void main(String[] args) {
        try {
            byte[] bt = new byte[1024];
            ServerSocket serverSocket = new ServerSocket();
            serverSocket.bind(new InetSocketAddress(8080));
            //等待链接:阻塞状态
            System.out.println("server start...");
            Socket accept = serverSocket.accept();
            System.out.println("connect success");

            //等待返回通知:阻塞状态
            int read = accept.getInputStream().read(bt);
            if(read != -1){
                System.out.println("result:"+new String(bt));
            }
        } catch (Exception e){
            System.out.println(e);
        }
    }
}

客户端实现:异步

public class Clients {

    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1",8080);
            socket.getOutputStream().write("返回结果".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

返回结果:socket

  该种方法优点在编写逻辑简单,无线程切换带来的cpu开销与不活跃线程形成的资源浪费;劣势也很明显,在等待链接与等待消息返回时会形成系统阻塞。ide

2.多线程实现

服务端实现:线程

public class Server {
    public static void main(String[] args) {
        try {
            byte[] bt = new byte[1024];
            ServerSocket serverSocket = new ServerSocket();
            serverSocket.bind(new InetSocketAddress(8080));
            while (true) {
                //等待链接:阻塞状态
                System.out.println("server start...");
                Socket accept = serverSocket.accept();
                System.out.println("connect success");

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            while (true) {
                                System.out.println("--------------------------");
                                int read = accept.getInputStream().read(bt);
                                if(read != -1){
                                    System.out.println("result:" + new String(bt));
                                }
                            }
                        } catch (Exception e) {
                            System.out.println(e);
                        }
                    }
                }).start();
            }
        } catch (Exception e){
            System.out.println(e);
        }
    }
}

建立多个客户端去调用,代码与单线程客户端相同,就不重复展现,输出结果以下: code

相关文章
相关标签/搜索