zoukankan      html  css  js  c++  java
  • 3. BIO(Blocking I/O)

    本章介绍:

      1.BIO基本介绍

      2.BIO工作机制

      3.BIO应用实例

      4.BIO问题分析


    一、BIO基本介绍

    1.Java BIO 就是传统的java io 编程,其相关的类和接口在 java.io
    2.BIO(blocking I/O) : 同步阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制改善(实现多个客户连接服务器)。
    3.BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,程序简单易理解

    二、BIO工作机制

        1.服务器端启动一个ServerSocket。
      2.客户端启动Socket对服务器进行通信,默认情况下服务器端需要对每个客户 建立一个线程与之通讯。
      3.客户端发出请求后, 先咨询服务器是否有线程响应,如果没有则会等待,或者被拒绝。
      4.如果有响应,客户端线程会等待请求结束后,再继续执行

    三、BIO应用实例

    实例说明:
      1. 使用BIO模型编写一个服务器端,监听6666端口,当有客户端连接时,就启动一个线程与之通讯。
      2. 要求使用线程池机制改善,可以连接多个客户端.
      3. 服务器端可以接收客户端发送的数据(telnet 方式即可)。

     1 public class BIOServer {
     2     public static void main(String[] args) throws Exception {
     3 
     4         //线程池机制
     5 
     6         //思路
     7         //1. 创建一个线程池
     8         //2. 如果有客户端连接,就创建一个线程,与之通讯(单独写一个方法)
     9 
    10         ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
    11 
    12         //创建ServerSocket
    13         ServerSocket serverSocket = new ServerSocket(6666);
    14 
    15         System.out.println("服务器启动了");
    16 
    17         while (true) {
    18 
    19             System.out.println("主线程信息 id =" + Thread.currentThread().getId() + " 名字=" + Thread.currentThread().getName());
    20             //监听,等待客户端连接
    21             System.out.println("等待连接....");
    22             final Socket socket = serverSocket.accept();//此处会阻塞
    23             System.out.println("连接到一个客户端");
    24 
    25             //就创建一个线程,与之通讯(单独写一个方法)
    26             newCachedThreadPool.execute(new Runnable() {
    27                 public void run() { //我们重写
    28                     //可以和客户端通讯
    29                     handler(socket);
    30                 }
    31             });
    32 
    33         }
    34     }
    35 
    36     //编写一个handler方法,和客户端通讯
    37     public static void handler(Socket socket) {
    38         try {
    39             System.out.println("socket线程信息 id =" + Thread.currentThread().getId() + " 名字=" + Thread.currentThread().getName());
    40             byte[] bytes = new byte[1024];
    41             //通过socket 获取输入流
    42             InputStream inputStream = socket.getInputStream();
    43             //循环的读取客户端发送的数据
    44             while (true) {
    45                 System.out.println("正在执行线程信息 id =" + Thread.currentThread().getId() + " 名字=" + Thread.currentThread().getName());
    46                 System.out.println("read....");
    47                int read =  inputStream.read(bytes);//此处会阻塞
    48                if(read != -1) {
    49                    System.out.println(new String(bytes, 0, read
    50                    )); //输出客户端发送的数据
    51                } else {
    52                    break;
    53                }
    54             }
    55         }catch (Exception e) {
    56             e.printStackTrace();
    57         }finally {
    58             System.out.println("关闭和client的连接");
    59             try {
    60                 socket.close();
    61             }catch (Exception e) {
    62                 e.printStackTrace();
    63             }
    64 
    65         }
    66     }
    67 } 

    1.执行程序

     

     2. 通过telnet方式建立两个连接

      3. 两个连接分别输入数据

    四、BIO问题分析

    1. 每个请求都需要创建独立的线程,与对应的客户端进行数据 Read,业务处理,数据 Write 。
    2. 当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大。
    3. 连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在 Read 操作上,造成线程资源浪费

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    HTML 页面的 批量删除的按钮
    HTML 选择器
    ....
    java 反射机制
    插件库
    向上滚动
    浮动元素定位float
    中文字体对应的英文名称
    echarts入门教程
    ie9浏览器window.openbug
  • 原文地址:https://www.cnblogs.com/qmillet/p/12142169.html
Copyright © 2011-2022 走看看