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

相關文章
相關標籤/搜索