IO通信模型(一)同步阻塞模式BIO(Blocking IO)

简介: 同步阻塞模式BIO

几个概念

阻塞IO 和非阻塞IO 这两个概念是程序级别的。主要描述的是程序请求操作系统IO操作后,如果IO资源没有准备好,那么程序该如何处理的问题:前者等待;后者继续执行(但是使用线程一直轮询,直到有IO资源准备好了)。

同步IO 和 异步IO,这两个概念是操作系统级别的。主要描述的是操作系统在收到程序请求IO操作后,如果IO资源没有准备好,该如何响应程序的问题:前者不响应,直到IO资源准备好以后;后者返回一个标记(好让程序和自己知道以后的数据往哪里通知),当IO资源准备好以后,再用事件机制返回给程序。

同步阻塞模式(Blocking IO)

同步阻塞IO模型是最简单的IO模型,用户线程在内核进行IO操作时如果数据没有准备号会被阻塞。

微信图片_20220221162122.png图片来源:www.masterraghu.com

伪代码表示如下:

{
    // 阻塞,直到有数据
    read(socket,buffer);
   process(buffer);
}

BIO通信方式的 特点

  1. 一个线程负责连接,多线程则为每一个接入开启一个线程。
  2. 一个请求一个应答。
  3. 请求之后应答之前客户端会一直等待(阻塞)。

BIO通信方式在单线程服务器下一次只能处理一个请求,在处理完毕之前一直阻塞。因此不适用于高并发的情况。不过可以使用多线程 稍微改进。

微信图片_20220221162827.png

Java同步阻塞模式

Java中的阻塞模式BIO,就是在 java.net包中的Socket套接字的实现,Socket套接字是TCP/UDP等传输层协议的实现。

Java同步阻塞模式编码

多线程客户端

为了测试服务端程序,可以先编写一个多线程客户端用于请求测试。

微信图片_20220221163750.png

微信图片_20220221164133.png

微信图片_20220221164314.png

单线程服务端

因为Java中的Socket就是BIO的模式,因此我们可以很简单的编写一个BIO单线程服务端。

SocketServer.java

微信图片_20220221164543.png

微信图片_20220221164653.png

多线程服务端

单线程服务器,在处理请求时只能同时处理一条,也就是说如果在请求到来时发现有请求尚未处理完毕,只能等待处理,因此使用 多线程改进服务端。

SocketServerThread.java

微信图片_20220221164953.png

微信图片_20220221165233.png

微信图片_20220221165546.png

看起来多线程增加了服务能力,但是很明显多线程改进之后仍有以下 局限性

  • 接收和通知处理结果的过程依旧是单线程的。
  • 系统可以创建的线程数量有限。 cat/proc/sys/kernel/threads-max可以查看可以创建的线程数量。
  • 如果线程较多,CPU需要更多的时间切换,处理真正业务的时间就会变少。
  • 创建线程会消耗较多资源,JVM创建一个线程都会默认分配128KB空间。
  • 多线程也无法解决因为 调用底层系统同步IO而决定的同步IO机制。

同步阻塞模式总结

BIO模式因为进程的阻塞挂起,不会消耗过多的CPU资源,而且开发难度低,比较适合并发量小的网络应用开发。同时很容易发现因为请求IO会阻塞进程,所以不时候并发量大的应用。如果为每一个请求分配一个线程,系统开销就会过大。

同时在Java中,使用了多线程来处理阻塞模式,也无法解决程序在 accept()read()时候的阻塞问题。因为 accept()read()的IO模式支持是基于操作系统的,如果操作系统发现没有套接字从指定的端口传送过来,那么 操作系统就会等待。这样 accept()read()方法就会一直等待。

GitHub源码

https://github.com/niumoo/java-toolbox


相关文章
|
Java Linux API
IO模型
BIO、NIO、AIO是Java中处理网络I/O的三种模型。BIO为阻塞式,每个连接需单独线程,高并发下性能受限;NIO通过非阻塞与多路复用提升并发能力,少量线程可处理大量请求;AIO进一步实现异步非阻塞,数据复制时线程可释放,由回调机制处理后续操作。三者适用于不同场景,BIO易用但低效,NIO高效但复杂,AIO理论性能更优但目前在Linux上仍依赖多路复用实现。Java 21引入虚拟线程后,BIO也可兼具高性能与易编写特性。
358 2
|
Ubuntu 网络协议 Unix
02理解网络IO:实现服务与客户端通信
网络IO指客户端与服务端通过网络进行数据收发的过程,常见于微信、QQ等应用。本文详解如何用C语言实现一个支持多客户端连接的TCP服务端,涉及socket编程、线程处理及通信流程,并分析“一消息一线程”模式的优缺点。
644 0
|
网络协议 前端开发 Java
网络协议与IO模型
网络协议与IO模型
648 4
网络协议与IO模型
|
缓存 网络协议 Java
JAVA网络IO之NIO/BIO
本文介绍了Java网络编程的基础与历史演进,重点阐述了IO和Socket的概念。Java的IO分为设备和接口两部分,通过流、字节、字符等方式实现与外部的交互。
584 0
|
开发者
什么是面向网络的IO模型?
【10月更文挑战第6天】什么是面向网络的IO模型?
217 3
|
缓存 Java Linux
硬核图解网络IO模型!
硬核图解网络IO模型!
390 1
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
9月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
362 1
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
1023 12