认识Java的Bio原理与不足

1.Bio与Nio的关系?

Nio是Bio的改进,但是Nio到底改进了什么?怎么实现的?有什么优势?等等问题都要从Bio找根源。

2.Bio是什么意思?

B I/O,意为Blocking I/O,即阻塞的I/O。
很明显重点在阻塞,但怎么就阻塞了?阻塞在哪了?阻塞带来了什么坏处?

3.Bio的工作模式

简单来说,在服务器中bio是一个连接由一个专门的线程来服务的工作模式。就像餐厅里来一个客人就给这个客人安排一个专用服务员,这个服务员就只服务这一个客人直到他离开为止。
如图所示每一个连接都享有一个线程的单独服务
在这里插入图片描述

4.Bio工作模式的缺陷

(1)线程创建资源开销巨大
如果有10000个连接怎么办?创建10000个线程?很明显不现实,太多的线程对系统资源的开销是巨大的。
(2)单个线程的资源浪费
一个请求来了,如果这个线程从被创建为这个连接服务开始就一直在工工作,那么就不存在资源浪费,就像你找来一个服务员,他只服务一个客人,但他期间一直都有工作作,那么他的劳动力就算不上浪费。
但是绝大多数情况下客人多服务员的需求都是暂时的,服务员很多时候都在发呆玩手机,等待着回应客人的请求,这样这个服务员的劳动力就被浪费了。那么在Bio中线程等待服务的时候是什么样的呢,那就是阻塞,线程等待着为连接服务(读数据/写数据/业务处理),很多时候BIo的服务子线程都是在阻塞状态下的。

5.Bio阻塞在哪了?

bio的阻塞,主要体现在两个地方,如代码中注释所示。
①若一个服务器启动就绪,那么主线程就一直在等待着客户端的连接,这个等待过程中主线程就一直在阻塞
②在连接建立之后,一个子线程服务于这个连接,那么这个子线程提供的服务无非就是socket通信,在读取到socket信息之前,这个子线程也是一直在等待,一直处于阻塞的状态下的。
注:代码中采用了连接池,这样可以节约一些线程重复创建的开销,但是这样的优化作用是有限的。
读者可以用windows 的telnet功能测试这个简单的服务器例子,以帮助加深对Bio的理解。

package com.zjl.bio;

import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @program: NettyTetst
 * @description: Bio的简单例子
 * @author: zoujunlin
 * @create: 2020-05-31 23:17
 **/
public class Bio implements Runnable{

    private  Socket socket;

    public  Bio(Socket socket){
        this.socket= socket;
    }
    public static void main(String[] args) {
        /*
        采用线程池机制

        1.创建一个线程池子
        2.每有一个请求就用一个线程来与之通信
        3.创建Socket服务
        4.监听链接
        5.打印客户端发送的字符
        * */

        ExecutorService executorsServics=Executors.newCachedThreadPool();//线程池
        try {
            ServerSocket serverSocket=new ServerSocket(1234);//注册serverSoket到1234端口
            System.out.println("服务器准备就绪...");
            while (true){
                final Socket socket = serverSocket.accept();//1线程在这里被阻塞,只要没有连接,就一直阻塞
                System.out.println("一个客户端连接到了服务器...");
                executorsServics.execute(new Bio(socket));//创建线程执行任务
            }
        }catch (Exception e){

        }
    }

    public void run() {
        byte[] bytes = new byte[1024];
        try{
            InputStream inputStream = socket.getInputStream();
            System.out.println("执行这个任务的线程是:"+Thread.currentThread().getName());
            while (true){//循环读取
                int read = inputStream.read(bytes);//2线程被阻塞的地方:只要读取不到数据就会一直阻塞
                if(read!=-1){
                    System.out.println(new String(bytes,0,read));//byte按坐标转String
                }else{
                    break;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                System.out.println("线程"+Thread.currentThread().getName()+"维护的连接中断了!");
                socket.close();//关闭socket连接
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

}



5 Nio

连接空值待补充。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值