Netty基础------ BIO

本文详细介绍了Java中的BIO( Blocking IO),包括其定义、工作原理及代码实操,阐述了BIO在处理并发连接时的限制及线程池优化,最后进行了总结。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Netty基础------ BIO(同步阻塞IO)

目录

Netty基础------ BIO

1、什么是BIO

2、BIO的工作机制

3、代码实操演示

4、总结


1、什么是BIO

  • Java BIo就是传统的 java io编程,其相关的类和接口在 java.io
  • BlO( blocking I/O):同步阻塞我们熟知的Socket编程就是BIO,每个请求对应一个线程去处理。一个socket连接一个处理线程(这个线程负责这个Socket连接的一系列数据传输操作)。阻塞的原因在于:操作系统允许的线程数量是有限的,多个socket申请与服务端建立连接时,服务端不能提供相应数量的处理线程,没有分配到处理线程的连接就会阻塞等待或被拒绝。
  • BO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,程序简单易理解。

2、BIO的工作机制

对BO编程流程的梳理:

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

针对上面的情况,我们可以使用线程池进行一定的优化。但这种优化仅仅是解决了频繁的创建线程的问题,不过由于是同步,如果读写速度慢,那么每个线程进来是会导致阻塞的,性能的高低完全取决于阻塞的时间。这个对于用户的体验也是相当不好的

如下:

3、代码实操演示

package com.BIO;

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

/**
 * @author: zps
 **/
public class BioServer {

    public static void main(String[] args) {
        //线程池
        ExecutorService executorService = Executors.newCachedThreadPool();

        try {
            ServerSocket serverSocket = new ServerSocket(8080);
            System.out.println("服务器已经启动!");

            while (true){
                Socket socket = serverSocket.accept();
                System.out.println("有一个客户端连接!");

                //放入线程池中处理请求
                executorService.execute(()->
                        handler(socket));
            }

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

    //处理请求
    private static void handler(Socket socket) {

        try {
            InputStream in = socket.getInputStream();
            byte[] bytes = new byte[1024];

            while (true){
                System.out.println("读到客户端发过来的消息为:");
                int read = in.read(bytes);
                if(read != -1){
                    System.out.println(new String(bytes , 0 , read));
                }else {
                    break;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {

            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
package com.BIO;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

/**
 * @author: zps
 **/
public class BioClient {
    public static void main(String[] args) {
        OutputStream os = null;
        Socket socket = null;
        try {
            socket = new Socket("localhost", 8080);
            os = socket.getOutputStream();
            Scanner sc = new Scanner(System.in);
            while (sc.hasNext()) {
                String msg = sc.nextLine();
                os.write(msg.getBytes());
            }
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

运行截图: 

4、总结

BIO其实就是一种同步阻塞的IO的操作。

阻塞和非阻塞是进程在访问数据的时候,数据是否准备就绪的一种处理方式,当数据没有准备的时候。

  • 阻塞:往往需要等待缓冲区中的数据准备好过后才处理其他的事情,否则一直等待在那里
  • 非阻塞:当我们的进程访问我们的数据缓冲区的时候,如果数据没有准备好则直接返回,不会等待。如果数据已经准备好,也直接返回。
从上面的实例中,客户端的每一个请求,服务端都会启动一个线程进行处理,并且会一直到客户端退出连接为止。但这样明显有一种缺点就是当客户端暂时没有发送的数据时,服务端的线程依旧会等待着,所以就会浪费了线程资源的浪费。那么就有了NIO,NIO与BIO的最大区别就是NIO是非阻塞的。
未完-----

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值